用属性替换实例的属性

ika*_*men 2 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>
Run Code Online (Sandbox Code Playgroud)

可以吗?什么是启用类属性的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
Run Code Online (Sandbox Code Playgroud)

L3v*_*han 6

可以吗?

这不可以.

属性是描述符,描述符只能在类级别声明.

建议允许实例描述符,但拒绝.


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

def attach_property(instance, key, prop):
    class Derived(instance.__class__):
        pass
    setattr(Derived, key, prop)
    instance.__class__ = Derived
Run Code Online (Sandbox Code Playgroud)

你可以这样使用:

a = Foo()
print(a.bar)
attach_property(a, "bar", property(lambda self: self._hidden))
print(a.bar)
Run Code Online (Sandbox Code Playgroud)