打印类的所有实例

90 投票
8 回答
116470 浏览
提问于 2025-04-11 19:43

在Python中,如果我有一个类,我该如何定义一个函数,让它以我设定的格式打印出这个类的每一个实例呢?

8 个回答

33

你不需要导入任何东西!只要使用“self”。下面是怎么做的:

class A:
    instances = []
    def __init__(self):
        A.instances.append(self) # suggested by @Herrivan
print('\n'.join(A.instances)) #this line was suggested by @anvelascos

就是这么简单。没有导入任何模块或库。

33

你需要在你的类里面创建一个静态列表,然后给每个实例添加一个 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)
127

在这种情况下,我看到有两个选择:

垃圾回收器

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

在这种情况下,所有的引用都会作为弱引用存储在一个列表中。如果你频繁创建和删除很多实例,记得在遍历后清理这个弱引用的列表,否则会有很多无用的东西留在里面。

另一个问题是,你需要确保调用基类的构造函数。你也可以重写 __new__ 方法,但在实例化时只会使用第一个基类的 __new__ 方法。这个方法也只适用于你可以控制的类型。

编辑:根据特定格式打印所有实例的方法留给你自己去练习,但基本上就是 for 循环的变种。

撰写回答