如何获取当前模块中一个类的所有实例
我有一个模块叫做 foo
,里面定义了一个类 Foo
,并创建了好几个这个类的实例。
从其他模块中,我可以通过 import foo
来获取一个 Foo
对象的列表,方法是:
[getattr(foo,f) for f in dir(f) if isinstance(getattr(foo,f), foo.Foo)]
如果我能在模块 foo
内部也做到这一点就太好了。但是按照现在的写法,名字 foo
在 foo
里面是没有意义的,换成 self
也没什么帮助。
有没有办法在这个模块内使用反射来找到这个类的所有实例呢?我希望能有一种方法,不用一个个地创建列表并添加每个实例。
1 个回答
8
目标: "
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
或其他模块中定义的工厂函数。
不过,如果你实际上是想获取某个模块中创建的所有实例,这其实是一个严重的编码问题;你可以考虑在那个模块中写一个工厂函数包装器,这个包装器只负责传递初始化参数并返回结果,同时跟踪已初始化的对象。