打印一个类的所有实例
使用Python中的类,如何定义一个函数来以函数中定义的格式打印该类的每个实例?
在这种情况下,我看到两个选项:
垃圾收集器
import gc for obj in gc.get_objects(): if isinstance(obj, some_class): dome_something(obj)
当你有很多对象的时候,它有很慢的缺点,但是你可以使用你无法控制的types。
使用mixin和weakrefs
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
在这种情况下,所有引用都会作为列表中的弱引用存储。 如果你经常创build和删除很多实例,你应该在迭代之后清理weakrefs列表,否则会出现很多问题。
在这种情况下的另一个问题是,你必须确保调用基类的构造函数。 你也可以重写__new__
,但是只有第一个基类的__new__
方法用于实例化。 这也只适用于你控制的types。
编辑 :根据特定的格式打印所有实例的方法是作为一个练习,但它基本上只是一个变体的循环。
您将需要在您的类上创build一个静态列表,并为每个实例添加一个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)
与几乎所有其他面向对象语言一样,将类的所有实例都保存在某种集合中。
你可以尝试这种事情。
class MyClassFactory( object ): theWholeList= [] def __call__( self, *args, **kw ): x= MyClass( *args, **kw ) self.theWholeList.append( x ) return x
现在你可以做到这一点。
object= MyClassFactory( args, ... ) print MyClassFactory.theWholeList
Python没有与Smallktalk的#allInstances等效,因为架构没有这种types的中心对象表(尽pipe现代的smalltalks并不像这样)。
另一个海报说,你必须明确地pipe理一个集合。 他build议维护一个registry的工厂方法是一个完全合理的方法来做到这一点。 你可能希望用弱引用做一些事情,所以你不必明确地跟踪对象的处理。
也许你的意思是像__str__
:
object.__str__(self)
由str()内置函数和print语句调用,以计算对象的“非正式”string表示forms。 这与repr ()的不同之处在于它不一定是有效的Pythonexpression式:可以使用更方便或简洁的表示。 返回值必须是一个string对象。
一个简单的例子:
>>> class dummy(object): ... def __init__(self): ... pass ... def __str__(self): ... return "I am a dummy" ... >>> d1=dummy() >>> d2=dummy() >>> print d1,d2 I am a dummy I am a dummy >>>
不清楚是否需要一次打印所有的类实例,或者是否初始化,或者如果您正在讨论一个您可以控制的类,而不是第三方库中的类。
无论如何,我会通过使用Python元类支持编写一个类工厂来解决这个问题。 如果您无法控制课程,请手动更新正在跟踪的课程或模块的__metaclass__
。
有关更多信息,请参见http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html 。