给定一个对象foo
(我有权访问)类A
(我无权访问)。
foo
有一个 x 属性,很多人都可以访问该属性,也可以设置foo.x
。
以某种方式可以用foo.x
替换@property
- 就像
foo.x = "bar"
从那时起会调用我指定的函数吗?如果是这样,之后是否也可以删除此属性并将其替换为例如foo.x = "not a property"
之类的内容?
请考虑:我无法访问该课程,只能访问该对象。
答案 0 :(得分:4)
你不能在一个实例上放置属性,没有。你必须对这个类进行猴子修补,或者对它进行子类化。
Monkey-patching将要求您使用不同的名称将原始属性存储在实例上的某个位置:
def getter(self):
try:
return self._x
except AttributeError:
# access the attribute on the instance directly.
try:
return self.__dict__['x']
except KeyError:
raise AttributeError('x')
def setter(self, value):
self._x = value
foo._x = foo.x
type(foo).x = property(getter, setter)
这会在类上设置property
对象。现在该类的所有实例都将拥有该属性!为了解决这个问题,如果没有x
属性,则上面的getter会回退到尝试从实例__dict__
获取原始_x
属性值。这应确保现有实例继续有效。
删除属性就像删除它一样简单:
del type(foo).x
请注意,此将与类属性冲突(例如,如果type(foo).x
是现有对象)。