打印类的所有实例打印类的所有实例(Printing all instances of a class

2019-05-10 16:42发布

在Python中的一类,我怎么定义一个函数来打印类的每个实例都在功能定义的格式?

Answer 1:

我认为在这种情况下两种选择:

垃圾收集器

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

在这种情况下,所有引用获取存储在列表中的弱引用。 如果您创建和删除大量实例的频繁,也应清理迭代后weakrefs的名单,否则将是一个很大的cruft。

在这种情况下,另一个问题是,你必须确保调用基类的构造函数。 您也可以覆盖__new__ ,但只有__new__第一基类的方法被实例化使用。 这也只适用于那些在你的控制类型。

编辑 :根据特定格式被留作练习打印所有实例的方法,但它基本上是一个在变化for -loops。



Answer 2:

你会想在你的类创建一个静态列表和添加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)


Answer 3:

非常好的和有用的代码,但它有一个很大的问题: 列表始终是做大这是从来没有清理的,以测试它只是添加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]


Answer 4:

同几乎所有其他的面向对象语言,保持类的所有实例某种形式的收藏。

你可以尝试这样的事情。

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


Answer 5:

Python没有一个相当于Smallktalk的#allInstances的架构没有这种类型的中央对象表(虽然现代smalltalks真的不喜欢那个工作,要么)。

至于其他的海报说,你必须明确地管理集合。 他维持一个注册表工厂方法的建议是做一个完全合理的方式。 您可能希望做的东西弱引用 ,这样你就不必明确跟踪对象的处置。



Answer 6:

目前尚不清楚,如果你需要在一次或当他们初始化打印所有类的实例,也没有如果你在谈论一个类,你可以控制VS在第三方库的类。

在任何情况下,我会写使用Python元类支持类工厂解决这个问题。 如果你没有在班级的控制,手动更新__metaclass__为您所跟踪的类或模块。

见http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html以获取更多信息。



文章来源: Printing all instances of a class
标签: python class