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 -- https://mail.python.org/mailman/listinfo/python-list