In the docs explaining properties, it is said:
Be sure to give the additional functions the same name as the original property (x in this case.)
I.e., the getter, setter and deleter methods must all have the same name.
Why? And also, Python forbids method overloading, doesn’t it?
EDIT:
Why does the following code fail when run in Python 2.6?
class Widget(object):
def __init__(self, thing):
self.thing = thing
print self.thing
@property
def thing(self):
return self._thing
@thing.setter
def set_thing(self, value):
self._thing = value
if __name__ == '__main__':
Widget('Some nonsense here')
Its output is:
Traceback (most recent call last):
File "widget.py", line 16, in <module>
Widget('Some nonsense here')
File "widget.py", line 3, in __init__
self.thing = thing
AttributeError: can't set attribute
The code works fine when set_thing() is renamed to thing().
Python does indeed not feature method overloading, but you’re correct that the docs encourage you to name the getters and setters identically, and demonstrates it to boot. What’s going on here?
The trick is to understand how method decorators work in Python. Whenever you see something like this:
what Python actually does under the covers is to rewrite it this way:
In other words: define a function
bar, then replace it with the result of callingfooon the bar function.While that’s all true, the order of evaluation is actually slightly different than the above when it comes to how names are resolved. It might be easier for you to pretend for a moment that what actually happens looks a bit closer to this:
Why does this matter? Let’s look at the Python in that documentation link:
Let’s rewrite this using what we now know to understand what Python is actually doing:
Now, we can actually see what’s going on: we’re not overloading functions; we’re gradually building up a
propertyobject that references other functions.It’s also worth noting that, depending on how you create the property, the names don’t need to match. Specifically, if you create the property explicitly with the
propertyfunction, as is done in the first example in the documentation, the names can be whatever you want; the example has them calledgetx,setx, anddelx, and it works fine. In what I assume is a safety precaution,property.setter,property.deleter, and the like do require the function passed have the same name, but they’re doing the same thing behind the scenes as the more explicitpropertyexample.