[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Instance vs Class variable oddity

I just saw some code that confused me.  The confusion has to do with class variables and instance variables.  In order to understand it better, I built this very small example:

class Test:
    x = 0

    def __init__(self, id):
        self.id = id

    def show(self):
        print('ID:', self.id, 'self.x is:', self.x)

    def increment(self):
        self.x = self.x + 1

# Create two instances of the Test object, each shows itself
t1 = Test('first')
t2 = Test('second')

# Ask t1 to increment itself twice

# Ask each to show themselves

# Let's see what the class has
print('Test.x is:', Test.x)

When I instantiate two objects (t1 and t2), the __init__ method calls the show method, which prints a value of self.x.  I'm not understanding why this is legal.  I would expect that I would get an error message saying that self.x does not exist, since no instance variable named self.x has been defined.  

However, this code runs fine, and gives the following output:

ID: first self.x is: 0
ID: second self.x is: 0
ID: first self.x is: 2
ID: second self.x is: 0
Test.x is: 0

My guess is that there is some scoping rule that says that if there is no instance variable by a given name, then see if there is one in the class.  If that is the case, then this line in the increment method seems odd:

self.x = self.x + 1

If the self.x on the right hand side refers to the class variable, and creates an instance variable called self.x on the left hand side, then how does the second call work using the value of the instance variable on the right hand side?  Can someone explain what's going on here?

Disclaimer:  I would never write code like this, but I saw this in someone else's code and didn't understand how it was working.