Alex Rivera | Logout

What in the world is the attribute "__class__" in python

Asked 2011-11-09T05:30:58.060
34

I have a question about __class__ in python.

The documentation says that __class__ is the class to which a class instance belongs. So I conducted a series of experiments:

class counter:
    count = 0
    def __init__(self):
            self.__class__.count += 1

NewCounter1 = counter()
print NewCounter1.count   #The result is 1
NewCounter2 = counter()
print NewCounter2.count   #The result is 2
print NewCounter2.__class__.count is NewCounter2.count  #result: True

Everything goes well.

Then I enter code as follows:

NewCounter2.__class__.count = 3

print NewCounter1.count                    #result:3
print NewCounter1.__class__.count      #result:3
print NewCounter2.count                    #result:3
print NewCounter2.__class__.count      #result:3
print NewCounter2.__class__.count is NewCounter2.count      #result: True

From the code above, I thought that maybe NewCounter1.count equals NewCounter1, or __class__.count, but the following code surprised me:

NewCounter2.count = 5

print NewCounter1.count                 #result:3
print NewCounter1.__class__.count   #result:3
print NewCounter2.count                 #result:5
print NewCounter2.__class__.count   #result:3
print NewCounter2.__class__.count is NewCounter2.count       #result: False

Why has NewCounter2.count changed but NewCounter2.__class__.count remained at 3? What's more, when I changed NewCounter2.count, NewCounter2.__class__.count is NewCounter2.count became False. What in the world is the attribute __class__ ?

Edit
Report

1 Answer

23

"From codes above, I thought that maybe NewCounter1.count equals NewCounter1. _class_.count"

The problem is that at the moment of this sentence in your question, after the only instructions:

NewCounter1 = counter()
NewCounter2 = counter()
NewCounter2.__class__.count = 3

having created NewCounter1 and NewCounter2
and having modified the class attribute counter.count,
there are no objects NewCounter1.count nor NewCounter2.count in existence, and then "equals" has no real meaning.

.

See the creation of NewCounter1 and just after:

class counter:
    count = 0
    def __init__(self):
        self.__class__.count += 1

print 'counter.count BEFORE ==',counter.count  # The result is 0
NewCounter1 = counter()
print '\nNewCounter1.__dict__ ==',NewCounter1.__dict__  # The result is {}
print 'NewCounter1.count    ==',NewCounter1.count # The result is 1
print 'counter.count AFTER  ==',counter.count  # The result is 1

NewCounter._dict_ is the namespace of the instance NewCounter1
print NewCounter1.count prints the same as print counter.count
However, 'count' (the string 'count') isn't in the namespace of NewCounter1, that is to say there is no attribute count in the namespace of the created instance !

How is it possible ?

That's because the instance is created without assignement to a 'count' identifier inside the _init_
-> there is no real creation of any attribute as a field in NewCounter1, that is to say no creation of INSTANCE attribute.

The consequence is that when the instruction
print 'NewCounter1.count ==',NewCounter1.count

answered 2011-11-09T15:05:27.493

Your Answer