在不可用的类中使用描述符 – python
发布时间:2020-12-16 21:30:06 所属栏目:Python 来源:网络整理
导读:使用 python描述符时的常见设计模式是使描述符使用该描述符保留实例字典.例如,假设我想创建一个计算访问次数的属性: class CountingAttribute(object): def __init__(self): self.count = 0 self.value = Noneclass MyDescriptor(object): def __init__(sel
使用
python描述符时的常见设计模式是使描述符使用该描述符保留实例字典.例如,假设我想创建一个计算访问次数的属性:
class CountingAttribute(object): def __init__(self): self.count = 0 self.value = None class MyDescriptor(object): def __init__(self): self.instances = {} #instance -> CountingAttribute def __get__(self,inst,cls): if inst in self.instances: ca = self.instances[inst] else: ca = CountingAttribute() self.instances[inst] = ca ca.count += 1 return ca class Foo(object): x = MyDescriptor() def main(): f = Foo() f.x f.x print("f.x has been accessed %d times (including the one in this print)"%(f.x.count,)) if __name__ == "__main__": main() 这是一个完全愚蠢的例子,没有做任何有用的事情;我试图孤立主要观点. 问题是我不能在一个不可清除的类中使用这个描述符,因为该行 self.instances[inst] = ca 使用实例作为字典键.处理这种情况有没有明智的方法?例如,一个人立即想要使用实例的id,但我不确定这样做是否会破坏应该如何使用哈希. 编辑:我意识到实例应该像weakref.WeakKeyDictionary,但我试图在这里保持简单,专注于可持续性的问题. 解决方法
您可以使用id(inst)作为密钥.
请注意,这不包括销毁对象并使用新ID创建新对象的情况. 为了正确检测这一点,您应该将ca和weakref存储在字典中.如果您检测到weakref的引用对象已消失,则必须假设重用给定的id. 就像是 import weakref class MyDescriptor(object): def __init__(self): self.instances = {} #instance -> CountingAttribute def __get__(self,cls): if inst is None: return self.instances # operating on the class,we get the dictionary. i = id(inst) if i in self.instances: ca,wr = self.instances[i] if wr() is None: del self.instances[i] if i not in self.instances: ca = CountingAttribute() self.instances[i] = (ca,weakref.ref(inst)) ca.count += 1 return ca 这可以解除与WeakKeyDictionary相关的可选性问题. 但也许你根本不需要这个词.一种完全不同的方法可能是 class MyDescriptor(object): def __get__(self,cls): if inst is None: return self,cls try: ca = inst.__the_ca except AttributeError: ca = inst.__the_ca = CountingAttribute() ca.count += 1 return ca 这种方法也有其缺点.例如,您不能在类中多次使用描述符而不会使其变得丑陋.因此,只应谨慎使用.第一种解决方案虽然更复杂,但却是最简单的解决方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |