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

Reply via email to