我的任务是创建一个可迭代类,该类在 iter 上返回已从此类创建的实例列表中的迭代器,例如:
x = SomeClass()
y = SomeClass()
for obj in SomeClass:
print obj
>><__main__.SomeClass object at .......> and etc
我是通过元类和 globals() 实现的。它看起来很糟糕,但它确实有效。我想找到一种更优雅和pythonic的方式;起初我想通过弱引用来实现,但我不明白如何从我的元类中获取工作类的一些变量,当我尝试在我的元类中的对象上存储引用时,它正在创建对我的引用类,所以这是我的实现:
class ObjectsInMemory(object):
class __metaclass__(type):
def __init__(self, *args, **kwargs):
self.name = args[0]
def __iter__(self):
glob = globals().copy()
cls_inst = []
for _, v in glob.iteritems():
try:
if self.name in v.__repr__():
cls_inst.append(v)
except TypeError:
pass
yield cls_inst
请您参考如下方法:
如果您想跟踪某个类的实例,我建议为此使用弱引用容器,例如 weakref.WeakSet。这种容器类的代码草图:
import weakref
class InstanceTracker(object):
def __init__(self):
self.instances = {}
def new(self, cls, *args, **kwargs):
instance = cls(*args, **kwargs)
self.instances.setdefault(cls, weakref.WeakSet()).add(instance)
return instance
def iter_instances(cls):
return iter(self.instances[cls])
您现在可以使用 tracker.new(SomeClass) 为 InstanceTracker 实例 tracker 创建新的 SomeClass 实例>.
这样,您就不必依赖全局状态,您的函数不会产生奇怪的副作用,并且您无需修改类来跟踪其实例。
