I re-wrote the entire class from scratch in a separate file and everything magically worked, conditionals and all. So, I simply imported that class and a couple functions from the new file into the master file. I still have no idea what went wrong the first time around.
Note the issues below were technically solved. You can see a typo towards the bottom of the code. That, however, uncovered an issue where all of my conditionals (if, try, etc.) stopped functioning, which is why I re-wrote the class in a separate module
I would delete this post since it got everyone nowhere, but that's not how things work on Stack Overflow, apparently.
Alright, I've been learning Python 3.4 and decided to do some homework on the side as practice. I started making a script that does a very basic simulation of 2 people fighting, and would expand upon it with any new stuff I learn (such as adding a GUI).
The script started out fine, but the more changes I made the more errors started showing up. Now it's to the point where I can't access any fields of the "fighter" class without it throwing errors such as:
'duelist' object has no attribute '_duelist__health'
Besides "'duelist' object has no attribute '_duelist__XXX'", I've had 0 other errors besides typos. Google unfortunately couldn't help with this one, so that's why I'm making my first StackOverflow post.
Here's the class down to the first error-happy field, "health":
class duelist:
def __init__(self):
self.name = "Duelist" #must not be ""
self.health = 5 #must be >0
self.damage = [1, 3] #random attack range. Must be >=0 0 and the first must not be higher.
self.skill = 10 #% chance to pass a skill check. Representative of parrying/dodging. Must be >=0
self.shield = True #can block?
self.shieldE = 80 #max block %. Must be >0
self.agility = 0.5 #rate of attack in seconds. Must be >=0.05
self.precision = 10 #critical hit chance. Must be >=0
self.critical = 2.0 #critical multiplier. Must be >= 1.1
#name
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
if value != "":
self.__name = value
else:
print("Invalid Name.\n")
#name
#health
@property
def health(self):
return self.__health
@health.setter
def health(self, value):
try:
value = value(int)
if value>=1:
self.__health = value
else:
print("Health must be above 0.\n")
except:
print("Invalid Health.\n")
#health
Also, for those suggesting to change the field names to not include an ' __ ' (or to include an ' __ ' everywhere), that causes an infinite loop. Typing exactly this:
class duelist:
def __init__(self):
self.health = 5
@property
def health(self):
return self.__health
@health.setter
def health(self, value):
self.__health = value
D = duelist()
print(D.health)
D.health = 15
print(D.health)
Correctly returns
5
15
Your code does:
.name =
inside __init__()
.__name =
.name
that reads through the getter, and reads .__name
And your description of the problem "I can't access any fields of the "fighter" class", I suspect is wrong, because accessing some of them work.
Health doesn't, though, and on line 45 you have this:
value = value(int)
instead of
value = int(value)
So that causes the getter to throw an exception and print("Invalid Health.\n")
and __health
is never set.
With self.shield = True
, the setter is trying to do:
if value.lower() == 'y':
and you can't call lower()
on a boolean, so it crashes out before it ever gets to try to type(value) == bool
, and __shield
is never set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With