I was wondering, what happens if a method and a attribute has the same name in a class. Will the program first search for the attribute in a object and if a method in a class has the same name, will the program skip it and just focus on the object?
-
It will be the one that is defined the latestVolatility– Volatility2013-02-07 09:23:55 +00:00Commented Feb 7, 2013 at 9:23
-
An easy way to answer this question would be to write such a class and see what happens.cms_mgr– cms_mgr2013-02-07 09:24:46 +00:00Commented Feb 7, 2013 at 9:24
-
methods are just objects like strings, ints, lists, etc. What you think of as a "method" is just an object that is referred to by an attribute.John La Rooy– John La Rooy2013-02-07 12:57:20 +00:00Commented Feb 7, 2013 at 12:57
2 Answers
It depends on which one is assigned first.
If the method is assigned first, the attribute will be the one you will access,
e.g.
class Example(object):
def __init__(self):
self.x = 44
def x(self):
return "hi"
print Example().x
Methods are "assigned" when the class is processed, where as x is assigned at initialization. This means that x overwrites the method.
This is of course different for class level attributes because they are assigned at the same time as the method
class Example(object):
x = 43
def x(self):
return "hi"
print Example().x
Shows that the method overwrites the attribute.
4 Comments
x attribute assigned then assign Example.x = <some function> and you've assigned the method second but the instance attribute still takes precedence. Also as I explain in my answer the object in the class will take precedence if it is a descriptor.Jakob's answer is mostly accurate but incomplete. If the x defined in the class follows the descriptor protocol and has __get__ and __set__ methods defined then it will continue to take precedence over any 'x' in the instance dictionary. The simplest way to see this is to use a property:
>>> class Example(object):
def __init__(self):
self.x = 44
@property
def x(self):
return "hi"
@x.setter
def x(self, value):
self.__dict__['x'] = value
>>> Example().x
'hi'
>>> Example().__dict__['x']
44
So the actual rule is that Python looks in the class (and its bases), and if it finds a matching object and the object has a __get__ method (or __set__ if setting) then it calls the __get__ method otherwise it looks for an instance attribute and uses that if there is one or if not falls back to using the class attribute (i.e. the method).
The lookup may be further complicated if either __getattribute__ or __getattr__ is defined.