Case Statements
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Thu Mar 17 02:29:35 EDT 2016
On Thursday 17 March 2016 16:45, Gregory Ewing wrote:
> Steven D'Aprano wrote:
>> On Thu, 17 Mar 2016 11:31 am, Chris Angelico wrote:
>>
>>> orig = globals()[cls.__name__]
>>
>> I wouldn't want to rely on it working with decorator syntax either. Even
>> if it does now, I'm not sure that's a language guarantee.
>
> The following idiom relies on similar behaviour:
>
> @property
> def x(self):
> return self._x
>
> @x.setter
> def x(self, value):
> self._x = value
>
> That's taken from the official docs, so I don't think
> this is likely to change any time soon.
I don't think that property is a similar situation. I think what happens
here is that the first call to property sets:
# @property def x...
x = property(x)
Then the second decorator does:
# @x.setter def x...
x = x.setter(x)
which replaces x with a brand new property object.
What happens if you use different names?
@property
def x(self):
pass
@x.setter
def y(self, arg):
pass
Now you have two different properties:
py> x
<property object at 0xb756eb1c>
py> y
<property object at 0xb756ef04>
Both x and y's getter points to the same function (our original def x):
py> y.fget
<function x at 0xb7564a04>
py> x.fget
<function x at 0xb7564a04>
But x's setter is None, while y has a valid setter:
py> x.fset is None
True
py> y.fset
<function y at 0xb7582ca4>
I don't think that either x or y will misbehave, but the behaviour will
certainly be surprising if you're not expecting it.
I think the documentation in Python 2.7 is misleading. help(x.setter) says:
setter(...)
Descriptor to change the setter on a property.
which is, I believe, a lie. It doesn't "change the setter" (modify the
property object in place), but returns a new property object. Here's my
pseudo-code for what I think property.setter does:
class property:
def setter(self, func):
return property(self.fget, func, self.fdel, self.__doc__)
As far as I can tell, none of this behaviour relies on the decorator being
called before the name of the decorated thing is bound.
--
Steve
More information about the Python-list
mailing list