python-打印类的所有实例
对于Python中的类,如何定义函数以函数中定义的格式打印类的每个实例?
user33061 asked 2019-12-25T05:00:09Z
7个解决方案
85 votes
在这种情况下,我看到两个选择:
垃圾收集器
import gc
for obj in gc.get_objects():
if isinstance(obj, some_class):
dome_something(obj)
当您有很多对象时,这样做的缺点是速度很慢,但是可以使用无法控制的类型。
使用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
在这种情况下,所有引用都将作为弱引用存储在列表中。 如果您经常创建和删除很多实例,则应在迭代后清理弱引用列表,否则会产生很多麻烦。
这种情况下的另一个问题是,您必须确保调用基类的构造函数。 您也可以覆盖__new__,但实例化仅使用第一个基类的for方法。 这也仅适用于您所控制的类型。
编辑:根据特定格式打印所有实例的方法作为练习,但基本上只是for循环的一种变体。
Torsten Marek answered 2019-12-25T05:01:01Z
23 votes
您将要在您的类上创建一个静态列表,并向每个实例添加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)
MirkoT answered 2019-12-25T05:01:22Z
6 votes
非常好的代码和有用的代码,但是有一个大问题:列表总是更大,并且永远都不会被清除,要测试它,只需在get_instances方法的末尾添加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]
Fabio Caccamo answered 2019-12-25T05:01:51Z
3 votes
与几乎所有其他OO语言一样,将类的所有实例保留在某种类型的集合中。
您可以尝试这种事情。
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
S.Lott answered 2019-12-25T05:02:20Z
3 votes
Python没有与Smallktalk的#allInstances等效的东西,因为该体系结构没有这种类型的中央对象表(尽管现代的Smalltalk也不是那样)。
正如另一位发布者所说,您必须显式管理一个集合。 他建议的一种维护注册表的工厂方法是一种完全合理的方法。 您可能希望对弱引用进行某些操作,因此不必显式跟踪对象处置。
ConcernedOfTunbridgeWells answered 2019-12-25T05:02:45Z
2 votes
您无需导入任何内容! 只需使用“自我”即可。 这是你的做法
class A:
instances = []
def __init__(self):
self.__class__.instances.append(self)
@classmethod
def printInstances(cls):
for instance in cls.instances:
print(instance)
A.printInstances()
就这么简单。 没有导入模块或库
Илиян Илиев answered 2019-12-25T05:03:09Z
1 votes
目前尚不清楚是需要一次打印所有类实例,还是需要在初始化时打印它们,或者说的是您要控制的类还是第3方库中的类。
无论如何,我将通过使用Python元类支持编写类工厂来解决此问题。 如果您无法控制该类,请为要跟踪的类或模块手动更新__metaclass__。
有关更多信息,请参见[http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html]。
Daniel Naab answered 2019-12-25T05:03:38Z