【发布时间】:2021-12-25 11:05:19
【问题描述】:
我正在用 python 3.9 编写一些代码,最近刚刚发现了描述符。
我创建了一个如下所示的类:
import threading
class OuterClass():
class DecoratorTest():
def __init__(self,fget,fset=None) -> None:
self.fget=fget
self.fset=fset
self.event=threading.Event()
def __getattribute__(self, name: str):
return object.__getattribute__(self,name)
def __get__(self,obj,objtype=None):
return self.fget(obj)
def __set__(self,obj,value):
self.fset(obj,value)
self.event.set()
self.event.clear()
def setter(self,fset):
return type(self)(self.fget,fset)
def __init__(self):
self.random_value=10
@DecoratorTest
def test_property(self):
return self.random_value*2
@test_property.setter
def test_property(self,value):
self.random_value=value
我的意图是有一个装饰器,它将一个事件添加到被装饰的属性中,以便在更改属性时设置事件。这是我如何使用它的示例:
class_iteration=OuterClass()
def test_funct():
while True:
class_iteration.test_property.event.wait()
print("Changed!")
threading.Thread(target=test_funct).start()
class_iteration.test_property=100
问题是当我尝试获取事件时,它认为class_iteration.test_property 是一个 int 对象,因此会引发错误。我想知道在使用__getattribute__ 时是否有任何方法可以绕过__get__,以便我可以访问event 变量,或者我是否需要完全改变我的方法。
【问题讨论】:
-
你需要吸气剂吗?或者可以通过例如访问它吗?
instance.test_property.get? -
您可以从
__dict__的类中检索属性:OuterClass.__dict__['test_property'].event。警告:在您的示例中,Event将在所有OuterClass实例之间共享,因为DecoratorTest.__init__在定义OuterClass时被调用,而不是在实例化时调用。这就是为什么test_property在OuterClass.__dict__中,而不是在class_iteration.__dict__中的原因。您可以将调试print()添加到DecoratorTest.__init__以确保(应该打印两次,因为setter创建了然后实例化的新类)。
标签: python get descriptor getattribute