tags:

views:

73

answers:

1

I am relatively new to Python and was hoping someone could explain the following to me:

class MyClass:
  Property1 = 1
  Property2 = 2

print MyClass.Property1 # 1
mc = MyClass()
print mc.Property1 # 1

Why can I access Property1 both statically and through a MyClass instance?

+8  A: 

The code

class MyClass:
  Property1 = 1

creates a class MyClass which has a dict:

In [2]: MyClass.__dict__
Out[2]: {'Property1': 1, '__doc__': None, '__module__': '__main__'}

Notice the key-value pair 'Property1': 1. When you say MyClass.Property1, Python looks in the dict MyClass.__dict__ for the key Property1 and if it finds it, returns the associated value 1.

In [3]: MyClass.Property1
Out[4]: 1

When you create an instance of the class,

In [5]: mc = MyClass()

a dict for the instance is also created:

In [6]: mc.__dict__
Out[6]: {}

Notice this dict is empty. When you say mc.Property1, Python first looks in mc.__dict__ for the 'Property1' key. Since it does not find it there, it looks in the dict of mc's class, that is, MyClass.__dict__.

In [7]: mc.Property1
Out[8]: 1

Note that there is much more to the story of Python attribute access. (I haven't mentioned the important rules concerning descriptors, for instance.) But the above tells you the rule for most common cases of attribute access.

unutbu
+1 for detailed description of the mechanism, but this is also a perfect opportunity to explicitly state a fundamental property of Python: Almost everything is or acts a lot like an object, including class definitions.
Nicholas Knight
Thanks, that makes more sense.
Andre
"it looks in the dict of `mc`'s parent class" should read "it looks in the dict of `mc`'s class", no?
EoghanM
@EoghanM: Yes, that's better. Thanks!
unutbu