使用Python中的类,如何定义一个函数以函数中定义的格式打印类的每个单个实例?
在这种情况下,我看到两个选项:
import gc for obj in gc.get_objects(): if isinstance(obj, some_class): dome_something(obj)
这样做的缺点是,当你拥有大量对象时速度非常慢,但是使用你无法控制的类型.
from collections import defaultdict import weakref class KeepRefs(object): __refs__ = defaultdict(list) def __init__(self): self.__refs__[self.__class__].append(weakref.ref(self)) @classmethod def get_instances(cls): for inst_ref in cls.__refs__[cls]: inst = inst_ref() if inst is not None: yield inst class X(KeepRefs): def __init__(self, name): super(X, self).__init__() self.name = name x = X("x") y = X("y") for r in X.get_instances(): print r.name del y for r in X.get_instances(): print r.name
在这种情况下,所有引用都存储为列表中的弱引用.如果你经常创建和删除很多实例,你应该在迭代后清理weakrefs列表,否则会有很多错误.
在这种情况下的另一个问题是你必须确保调用基类构造函数.您也可以覆盖__new__
,但__new__
实例化时只使用第一个基类的方法.这也仅适用于您控制的类型.
编辑:根据特定格式打印所有实例的方法for
留作练习,但它基本上只是-loops 的变体.
您需要在类上创建静态列表,weakref
并向每个实例添加一个静态列表,以便垃圾收集器可以在不再需要实例时清理它们.
import weakref class A: instances = [] def __init__(self, name=None): self.__class__.instances.append(weakref.proxy(self)) self.name = name a1 = A('a1') a2 = A('a2') a3 = A('a3') a4 = A('a4') for instance in A.instances: print(instance.name)
非常好的代码和有用的代码,但是有一个大问题:列表总是更大,并且永远不会被清除,要测试它,只需print(len(cls.__refs__[cls]))
在get_instances
方法末尾添加即可。
这里是该get_instances
方法的修复:
__refs__ = defaultdict(list) @classmethod def get_instances(cls): refs = [] for ref in cls.__refs__[cls]: instance = ref() if instance is not None: refs.append(ref) yield instance # print(len(refs)) cls.__refs__[cls] = refs
或者,也可以使用WeakSet完成:
from weakref import WeakSet __refs__ = defaultdict(WeakSet) @classmethod def get_instances(cls): return cls.__refs__[cls]