The subject of Python properties is covered extensively here, and the Python documentation provides a pure Python implementation here. However, I am still not fully clear on the mechanics of the decorator functionality itself. More specifically, for identically named getters and setters x
, how does the setter function object x
(before being passed to the @x.setter decorator) not end-up rewriting the property object bound to x
(thus making the decorator call meaningless)?
Consider the following example:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
print("getter of x called")
return self._x
@x.setter
def x(self, value):
print("setter of x called")
self._x = value
@x.deleter
def x(self):
print("deleter of x called")
del self._x
From what I understand about decorators (please correct me if I'm wrong), @property
followed by def x(self): ...
in the getter definition is the pure equivalent of def x(self): ...
followed by x = property(x)
. Yet, when I try to replace all three decorators with the class constructor call syntax equivalent (while still keeping the function names identical), it stops working, like so:
class C(object):
def __init__(self):
self._x = None
def x(self):
"""I'm the 'x' property."""
print("getter of x called")
return self._x
x = property(x)
def x(self, value):
print("setter of x called")
self._x = value
x = x.setter(x)
def x(self):
print("deleter of x called")
del self._x
x = x.deleter(x)
... which results in AttributeError: 'function' object has no attribute 'setter'
on line 14 (x = x.setter(x)
).
This seems expected, since def x(self, value)...
for the setter should overwrite x = property(x)
from above.
What am I missing?