0

In the following code, the method name name is used three times within the same Person scope:

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):                 # name = property(name)
        "name property docs"
        print('fetch...')
        return self._name

    @name.setter
    def name(self, value):          # name = name.setter(name)
        print('change...')
        self._name = value

    @name.deleter
    def name(self):                 # name = name.deleter(name)
        print('remove...')
        del self._name

In theory, decorators are equal to a name rebinding. It shouldn't affect the scope. So in the above code the last name method should be the only surviving one that is being transformed by the decorators.

My question is, what mechanism enables the decorators to pick exactly the 'right' method, and not the last method which in theory should override all the previous ones?

Jinghui Niu
  • 990
  • 11
  • 28
  • 1
    Short version: `@property` decorator binds `name` to a `property` object that has methods for getting, setting, etc. The `@name.setter` decorator binds `name` to a property object equal to `name` with the setter method replaced by the given function. So `name` is being replaced each time, it's just being replaced by successively more detailed `property` objects. – Patrick Haugh Jan 08 '18 at 03:47
  • @PatrickHaugh So at the second replacement, how does Python tell the difference between property object `name` and target method `name`? There would be two `name` at that point. Of course we humans know it should be that the property object `name` to replace the method `name`, but just how does Python know it? – Jinghui Niu Jan 08 '18 at 04:00
  • That's the nice thing about decorators. `name` is only rebound once, when it's assigned to the new `property` object. At no point is there a `method` object bound to `name`. This is mentioned in [PEP 318](https://www.python.org/dev/peps/pep-0318/#current-implementation-history). It's equivalent to `name = name.setter()` – Patrick Haugh Jan 08 '18 at 04:07

0 Answers0