您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在不可用的类中使用描述符 – python

5b51 2022/1/14 8:20:16 python 字数 3853 阅读 467 来源 www.jb51.cc/python

使用 python描述符时的常见设计模式是使描述符使用该描述符保留实例字典.例如,假设我想创建一个计算访问次数的属性: class CountingAttribute(object): def __init__(self): self.count = 0 self.value = None class MyDescriptor(object):

概述

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创建新对象的情况.

为了正确检测这一点,您应该将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

这种方法也有其缺点.例如,您不能在类中多次使用描述符而不会使其变得丑陋.因此,只应谨慎使用.第一种解决方案虽然更复杂,但却是最简单的解决方案.

总结

以上是编程之家为你收集整理的在不可用的类中使用描述符 – python全部内容,希望文章能够帮你解决在不可用的类中使用描述符 – python所遇到的程序开发问题。


如果您也喜欢它,动动您的小指点个赞吧

除非注明,文章均由 laddyq.com 整理发布,欢迎转载。

转载请注明:
链接:http://laddyq.com
来源:laddyq.com
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


联系我
置顶