Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - object has no attribute Error

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
like image 531
FierySwordswoman Avatar asked Sep 18 '16 02:09

FierySwordswoman


1 Answers

Your code does:

  1. Set the value of .name = inside __init__()
  2. That goes through the setter, and sets .__name =
  3. When you read it by .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.

like image 147
TessellatingHeckler Avatar answered Oct 18 '22 07:10

TessellatingHeckler