用属性替换实例的属性

时间:2018-12-12 13:17:28

标签: python

我想用一个属性覆盖一个属性,但只能在一个实例上。 这是我尝试解决的方法,但是它没有实现我想要的功能:

class Foo:
    def __init__(self):
        self.bar = True
        self._hidden = False

a = Foo()
print(a.bar)
a.bar = property(lambda self: self._hidden)
print(a.bar)


>>> C:\Users\Ilya\AppData\Local\Programs\Python\Python37-32\python.exe C:/Users/Ilya/pydolons/experiment.py
>>> True
>>> <property object at 0x0323B960>

可以做到吗?启用类属性的dunder调用的实际机制是什么,而不是实例上设置的dunder调用的真正机制?

下面的代码可以完成我想做的事情,但是会修改该类:

class Foo:
    def __init__(self):
        self.bar = True
        self._hidden = False

a = Foo()
print(a.bar)
Foo.bar = property(lambda self: self._hidden)
print(a.bar)

>>> C:\Users\Ilya\AppData\Local\Programs\Python\Python37-32\python.exe C:/Users/Ilya/pydolons/experiment.py
>>> True
>>> False

1 个答案:

答案 0 :(得分:6)

  

能做到吗?

不能。

属性是描述符,并且只能在类级别上声明描述符。

允许的实例描述符为proposed, but rejected


如果可以将此实例迁移到其他类,可以这样做:

def attach_property(instance, key, prop):
    class Derived(instance.__class__):
        pass
    setattr(Derived, key, prop)
    instance.__class__ = Derived

您可以这样使用它:

a = Foo()
print(a.bar)
attach_property(a, "bar", property(lambda self: self._hidden))
print(a.bar)