【问题标题】:How do I get a reference to all classes implementing descriptor object in python如何获取对在 python 中实现描述符对象的所有类的引用
【发布时间】:2013-12-26 12:02:33
【问题描述】:

我正在创建一个描述符,我想在其中创建一个列表,其中包含对所有实现它的对象的引用,它应该是某种快捷方式,我可以在其中调用下一个实例的方法实例。

我能找到的唯一愚蠢的解决方案是在每个对象的__init__ 上触发将项目添加到列表的描述符上的设置器,即使该解决方案确实有效,但我可以感觉到它有问题。

除了在__init__ 上设置任意值之外,是否有更好的方法将类实例添加到描述符列表中,只是为了触发设置器?

class GetResult(object):
    def __init__(self, value):
        self.instances = []
    def __get__(self, instance, owner):
        return self
    def __set__(self, instance, value):
        self.instances.append(instance)
    def getInstances(self):
        return self.instances




class A(object):
    result = GetResult(0)
    def __init__(self):
        self.result = 0
    def getAll(self):
        print self.result.getInstances()




a1 = A()
a2 = A()
a3 = A()

print a2.result.getInstances()
>> [<__main__.A object at 0x02302DF0>, <__main__.A object at 0x02302E10>, <__main__.Aobject at 0x02302E30>]

【问题讨论】:

  • 您能否用一些代码来说明您的问题,例如可以工作但您认为不太理想的代码。
  • 除非您要将相同的描述符对象粘贴到多个类上,否则只需将实例列表放在类上而不是描述符上就可以了。
  • 另一方面,如果您想为所有带有GetResult 描述符的对象创建一个列表,即使它们使用GetResult 的不同实例,您可能希望粘贴实例列表到GetResult 类。您可以尝试使用类装饰器或元类将必要的逻辑添加到__init__,如果您这样做,还可能添加描述符。
  • 是的,布鲁诺在下面的回复中提到了同样的原则,我想如果没有其他想法,我可能会直接采用。

标签: python metaprogramming


【解决方案1】:

如果这就是你的描述符所做的一切,这有点滥用描述符协议。只需覆盖您的课程 __new____init__ 会更简单:

class Foo(object):
    _instances = []

    def __new__(cls, *args, **kw):
        instance = object.__new__(cls)
        cls._instances.append(instance)
        return instance

    @classmethod
    def get_instances(cls):
        return self._instances

【讨论】:

  • 以上内容在任何方面都不是滥用,它现在是一种规范。现在您也可以结合使用上述内容和依赖于主机类的描述符的简化版本来提供实例列表。
  • 是的,我意识到你刚才的意思,这就是我删除消息的原因,这是一个不错的方法,尽管我计划用更多功能扩展我的描述符,而不是简单地保留引用。
  • 我猜它的目的可以说是对象查找管理器。
  • 如果我以这种方式使用它,那是否也是对协议的滥用?
  • 对我来说,跟踪类实例确实不属于描述符 - 部分原因是它并不是描述符的真正用途,但好吧,我不会对 i 教条,但主要是您描述的问题:它不透明,需要班级的某种合作,一种或另一种方式。所以最好清楚地了解这一点并提供另一种方式(装饰器、类装饰器、基类、元类等)来提供实例跟踪部分。请注意,这种“其他方式”可以负责将描述符添加到类...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-14
相关资源
最近更新 更多