通常,基本上可以随意添加或修改对象属性,但是似乎无法修改现有的对象属性来更改底层的getter / setter / deleter函数。
例如,具有以下类别:
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'
如何更改现有对象上属性的基础getter / setter / deleters?