【问题标题】:How to obtain all instances of a class within the current module如何获取当前模块内某个类的所有实例
【发布时间】:2011-07-04 02:15:48
【问题描述】:

我有一个模块foo,它定义了一个类Foo,并实例化了该类的多个实例。

从其他模块,我可以import foo 并获得Foo 对象的列表:

[getattr(foo,f) for f in dir(f) if isinstance(getattr(foo,f), foo.Foo)]

如果我可以在模块foo 中执行此操作会很方便。但正如所写,foo 的名称在 foo 内部毫无意义,更改为 self 也无济于事。

有没有办法在这个模块中使用自省来查找这个类的所有实例?我希望有一种方法可以避免列出并附加每个实例。

【问题讨论】:

  • 我建议重命名这个“如何获取一个类的所有实例化实例”,假设这就是你想要做的。

标签: python module introspection


【解决方案1】:

goal: "import foo 并获取由...实例化的 Foo 对象的列表"

你根本不需要自省。想象这是你的班级:

class Registered(object):
    _all = set()
    def __init__(self):
        self.__class__._all.add(self)

演示;实例化一堆对象并引用它们:

>>> Registered()
>>> Registered()
>>> Registered()

>>> Registered._all
{<__main__.Registered object at 0xcd3210>, <__main__.Registered object at 0xcd3150>, <__main__.Registered object at 0xcd31d0>}

由于您使用的是dir,如果我理解正确,您正在尝试查找当前模块的全局变量中的所有对象。然而,它并没有真正得到当前模块中的所有对象,只有那些绑定到变量的对象。如果这是你真正想要的,你可以{var for name,var in globals() if isinstance(var,Foo)}

如果这不是您真正想要的,您可以修改上述内容以跟踪通过 inspect.currentframe().f_back.f_globals 或其他方式定义对象的模块,但这会阻止您使用在 foo.py 或其他模块。

如果您实际上是在尝试获取在模块中创建的东西的所有实例,那么这表明存在严重的编码问题;考虑在该模块中编写一个工厂函数包装器,它除了传递初始化参数并返回结果之外什么都不做,跟踪初始化的对象。

【讨论】:

  • 当我尝试这个时,我得到NameError: global name '__class__' is not defined
  • @FarmBoy:将__class__ 替换为Registered;这是在 python3 中做事的一种更好的方式(如果您决定更改类的名称,则不必每次使用时都替换它)
  • 您可以使用type(self)。或者改写__new__
  • self.__all__ 将与 setRegistered.__all__ 相同,只要您不分配给它__all__ 也是一个可怕的名字。它可能应该是_all__all,以两个下划线开头和结尾的名称保留供python 将来定义,并且由于__all__ 在python 中没有特别使用,它不应该与保留模式匹配。
  • 我建议对集合中的对象使用弱引用。否则很难收集到。
猜你喜欢
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 2015-03-13
  • 2010-10-08
  • 2021-10-11
  • 2019-01-29
相关资源
最近更新 更多