On Thu, Mar 17, 2016 at 5:29 PM, Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > 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.
Okay. Let's try this. >>> class Demo: ... @property ... def x(self): ... print("Getting x") ... return 42 ... @x.setter ... def x(self, value): ... print("Setting x to", value) ... >>> d = Demo() >>> d.x Getting x 42 >>> d.x = 1 Setting x to 1 Decorators work. Now let's try NOT using decorators. >>> class Demo: ... def x(self): ... print("Getting x") ... return 42 ... x = property(x) ... def x(self, value): ... print("Setting x to", value) ... x = x.setter(x) ... Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 8, in Demo AttributeError: 'function' object has no attribute 'setter' Since the 'def' line bound the undecorated function to the name 'x', the decoration underneath *fails*. The only way this could work would be with a temporary name for either the new function or the decorator: >>> class Demo: ... def x(self): ... print("Getting x") ... return 42 ... x = property(x) ... decorator = x.setter ... def x(self, value): ... print("Setting x to", value) ... x = decorator(x) ... del decorator ... >>> d = Demo() >>> d.x Getting x 42 >>> d.x = 1 Setting x to 1 This is how CPython implements this (it evaluates the decoration expressions first, leaving them on the stack, then creates the function, then calls the decorators), but I don't see anywhere that this is guaranteed in the docs either - the only way I know this is current behaviour is from trying it (with dis.dis). The documented equivalence simply doesn't work. Note, by the way, that I am not in any way criticising the *behaviour* here. I don't think anything needs to be changed as regards functionality. And it's not even that big an issue as regards documentation. It's mainly just an esoteric curiosity. ChrisA -- https://mail.python.org/mailman/listinfo/python-list