How does python differentiate a class attribute, instance attribute, and method when the names are the same?
class Exam(object):
test = "class var"
def __init__(self, n):
self.test = n
def test(self):
print "method : ",self.test
test_o = Exam("Fine")
print dir(test_o)
print Exam.test
print test_o.test
test_o.test()
Output :
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'test']
<unbound method load.test>
Fine
Traceback (most recent call last):
File "example.py", line 32, in <module>
test_o.test()
TypeError: 'str' object is not callable
How to call
Exam.test
--> <unbound method load.test>
output shows methodtest_o.test
--> "Fine"
test_o.test()
--> TypeError: 'str' object is not callable
Class attributes are accessible through the class:
YourClass.clsattribute
or through the instance (if the instance has not overwritten the class attribute):
instance.clsattribute
Methods, as stated by ecatmur in his answer, are descriptors and are set as class attributes.
If you access a method through the instance, then the instance is passed as the self
parameter to the descriptor.
If you want to call a method from the class, then you must explicitly pass an instance as the first argument. So these are equivalent:
instance.method()
MyClass.method(instance)
Using the same name for an instance attribute and a method will make the method hidden via the instance, but the method is still available via the class:
#python3
>>> class C:
... def __init__(self):
... self.a = 1
... def a(self):
... print('hello')
...
>>> C.a
<function a at 0x7f2c46ce3c88>
>>> instance = C()
>>> instance.a
1
>>> C.a(instance)
hello
Conclusion: do not give the same name to instance attributes and methods. I avoid this by giving meaningful names. Methods are actions, so I usually use verbs or sentences for them. Attributes are data, so I use nouns/adjectives for them, and this avoids using the same names for both methods and attributes.
Note that you simply cannot have a class attribute with the same name as a method, because the method would completely override it (in the end, methods are just class attributes that are callable and that automatically receive an instance of the class as first attribute).