定义对象实例的属性

时间:2016-02-23 10:50:03

标签: python properties

给定一个对象foo(我有权访问)类A(我无权访问)。

foo有一个 x 属性,很多人都可以访问该属性,也可以设置foo.x

以某种方式可以用foo.x替换@property - 就像

这样的分配
foo.x = "bar"

从那时起会调用我指定的函数吗?如果是这样,之后是否也可以删除此属性并将其替换为例如foo.x = "not a property"之类的内容?

请考虑:我无法访问该课程,只能访问该对象。

1 个答案:

答案 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是现有对象)。