Reputation: 144
So i made a class and want, that attribute hp stays always between 0 and maxhp In theory making hp a property should give me the wished result: Somehow it doesnt work though.
Is there way to link attributes for and back? So i have stored the position of the unit class object. At 2 places, once the attribute position which contains a [x,y] array and the other time its stored in 2 attributes x and y and each contains a int. Changing self.x or self.y should changes self.position and the other way around too.
class units(object):
def __init__(self,typus, position, stats):
self.type = typus
#they should be linked both directions
self.position = position
self.x = self.position[0]
self.y = self.position[1]
self.attack = stats[0]
self.defense = stats[1]
self.maxhp = stats[2]
self.hp = self.maxhp
def __repr__(self):
text = "This a %s at position [%s,%s].\n Attack: %s \n Defense: %s \n Hp : %s/%s \n " \
% (self.type,self.position[0],self.position[1], self.attack, self.defense, self.hp, self.maxhp)
return text
# hp set to always be in between 0 and maxhp
@property
def hp(self):
return self.__hp
@hp.setter
def hp(self, hp):
if hp < 0:
self.__hp = 0
if hp > self.maxhp:
self.__hp = self.maxhp
else:
self.__hp = hp
def takedmg(self,dmg):
self.hp -= max(dmg-self.defense, 0)
if self.hp <= 0:
self.alive = False
return self.hp
p = units("peasant", [1,1], [2,0,30])
p.takedmg(100)
print (p.hp) # it should be 0!
Upvotes: 0
Views: 98
Reputation: 390
Another problem is in hp.setter
. The second if
statement should be replaced with elif
because when hp
is less than 0, self.__hp
is set to 0 in first if
and then, without elif
, it is set to a negative value in else
:
@hp.setter
def hp(self, hp):
if hp < 0:
self.__hp = 0
elif hp > self.maxhp:
self.__hp = self.maxhp
else:
self.__hp = hp
Upvotes: 1
Reputation: 15987
In your __init__
, the line self.hp = self.maxhp
should be self.__hp = self.maxhp
. That way it's only set/get in the @property
methods.
You would handle postion
, x
and y
the same way as you've done for hp
. Use _postion
, _x
and _y
internally to correspond to the values in the getters and setters; and set all of the _prop
values in the setters of each. Using position
as a an example:
@property
def position(self):
return self._position
@position.setter
def position(self, position):
self._position = position # do checking before this if needed
self._x = position[0]
self._y = position[1]
Similarly for x
and y
, though I think you should only do it via position
:
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
# self._y remains unchanged
self._position[0] = x
Btw, the hp
setter can be re-written as follows:
@hp.setter
def hp(self, hp):
self.__hp = max(0, min(hp, self.maxhp))
Upvotes: 0