Как изменить свойство getter / setter / deleters для существующего объекта? - PullRequest
0 голосов
/ 02 января 2019

Как правило, можно добавлять или изменять атрибуты объекта по существу по своему усмотрению, но, по-видимому, невозможно изменить существующее свойство объекта для изменения базовых функций получения / установки / удаления.

Например, со следующим классом:

class Foo:
    def __init__(self, x):
        self._x = x
    def get_x(self):
        print("get_x function!")
        return self._x
    @property
    def x(self):
        print("x property getter!")
        return self._x

Нетрудно заменить get_x другой функцией:

In [1]: foo = Foo('foo')
   ...: foo.get_x()
get_x function!
Out[1]: 'foo'

In [2]: foo.get_x = lambda: 'something else'
   ...: foo.get_x()
Out[2]: 'something else'

И не сложно связать внешнюю функцию с объектом, так что он может принять self:

def bind(instance, value):
    return value.__get__(instance, instance.__class__)

Тогда:

In [3]: foo.get_x = bind(foo, lambda self: 'modified ' + self._x)
   ...: foo.get_x()
Out[3]: 'modified foo'

Мне известно, что это назначение только затеняет первоначальное определение, а не фактически заменяет его, но

Однако, если я попытаюсь заменить x, свойство уже будет иметь контроль = и setattr. Я мог бы попробовать что-то вроде:

In [4]: foo.x = property(bind(foo, lambda self: 'modified ' + self._x))
AttributeError: can't set attribute

Но даже если бы это работало, это было бы бессмысленно, так как результатом был бы сам объект свойства, а не доступ к нему:

In [5]: foo.y = property(bind(foo, lambda self: 'modified ' + self._x))
   ...: foo.y
Out[5]: <property at 0x220e9780548>

И хотя изменение базового класса работает, я не хочу изменять всех экземпляров, только один:

In [6]: foo.__class__.x = property(lambda self: 'modified ' + self._x)
   ...: foo.x
Out[6]: 'modified foo'

In [7]: bar = Foo('bar')
   ...: bar.x # don't want this to have changed
Out[7]: 'modified bar'

Как я могу изменить базовый метод получения / установки / удаления свойства существующего объекта?

...