Python - object has no attribute Error
<p><strong>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.</strong></p>

<p><strong>Note the issues below were <em>technically</em> 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</strong></p>

<p><strong>I <em>would</em> delete this post since it got everyone nowhere, but that's not how things work on Stack Overflow, apparently.</strong></p>

<p>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).</p>

<p>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:</p>

<pre><code>'duelist' object has no attribute '_duelist__health'
</code></pre>

<p>Besides "<em>'duelist' object has no attribute '_duelist__XXX'</em>", 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.</p>

<p>Here's the class down to the first error-happy field, "health":</p>

<pre><code>class duelist:
    def __init__(self):
        self.name = "Duelist" #must not be ""
        self.health = 5 #must be &gt;0
        self.damage = [1, 3] #random attack range. Must be &gt;=0 0 and the first must not be higher.
        self.skill = 10 #% chance to pass a skill check. Representative of parrying/dodging. Must be &gt;=0
        self.shield = True #can block?
        self.shieldE = 80 #max block %. Must be &gt;0
        self.agility = 0.5 #rate of attack in seconds. Must be &gt;=0.05
        self.precision = 10 #critical hit chance. Must be &gt;=0
        self.critical = 2.0 #critical multiplier. Must be &gt;= 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&gt;=1:
                self.__health = value
            else:
                print("Health must be above 0.\n")
        except:
            print("Invalid Health.\n")
    #health
</code></pre>

<p>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:</p>

<pre><code>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)
</code></pre>

<p>Correctly returns </p>

<pre><code>5
15
</code></pre>

<p>Your code does:</p>

<ol>
<li>Set the value of <code>.name =</code> inside <code>__init__()</code></li>
<li>That goes through the setter, and sets <code>.__name =</code></li>
<li>When you read it by <code>.name</code> that reads through the getter, and reads <code>.__name</code></li>
</ol>

<p>And your description of the problem "<em>I can't access any fields of the "fighter" class</em>", I suspect is wrong, because accessing <em>some</em> of them work.</p>

<p>Health doesn't, though, and on line 45 you have this:</p>

<pre><code>value = value(int)
</code></pre>

<p>instead of</p>

<pre><code>value = int(value)
</code></pre>

<p>So that causes the getter to throw an exception and <code>print("Invalid Health.\n")</code> and <code>__health</code> is never set.</p>

<p>With <code>self.shield = True</code>, the setter is trying to do:</p>

<pre><code>if value.lower() == 'y':
</code></pre>

<p>and you can't call <code>lower()</code> on a boolean, so it crashes out before it ever gets to try to <code>type(value) == bool</code>, and <code>__shield</code> is never set.</p>

python object attributes field