Python 打印类的所有实例

Python 打印类的所有实例,python,class,Python,Class,对于Python中的类,如何定义一个函数,以该函数中定义的格式打印该类的每个实例?与几乎所有其他OO语言一样,将该类的所有实例保留在某种类型的集合中 你可以试试这种东西 class MyClassFactory( object ): theWholeList= [] def __call__( self, *args, **kw ): x= MyClass( *args, **kw ) self.theWholeList.append( x )

对于Python中的类,如何定义一个函数,以该函数中定义的格式打印该类的每个实例?

与几乎所有其他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

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

垃圾收集器 这样做的缺点是,当您有很多对象时,速度非常慢,但可以处理无法控制的类型

使用混合器和weakrefs 在这种情况下,所有引用都作为弱引用存储在列表中。如果您经常创建和删除大量实例,那么应该在迭代后清理weakrefs列表,否则会有很多缺点

这种情况下的另一个问题是,必须确保调用基类构造函数。也可以重写
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,但实例化时只使用第一个基类的
\uuuuuuuuuuuuuuuu。这也仅适用于您控制的类型


Edit:根据特定格式打印所有实例的方法留作练习,但它基本上只是
for
-循环的一种变体。

Python没有与Smallktalk的#allInstances等效的方法,因为体系结构没有这种类型的中心对象表(尽管现代的小型会谈也不是这样的)


正如另一张海报所说,你必须显式地管理一个集合。他建议使用一个工厂方法来维护一个注册表,这是一个非常合理的方法。你可能希望用它做一些事情,这样你就不必显式地跟踪对象的处理。

不清楚你是否需要一次打印所有类实例,或者它们是初始化的,如果你说的是一个你可以控制的类,也不是第三方库中的类

在任何情况下,我都可以通过使用Python元类支持编写一个类工厂来解决这个问题。如果您无法控制该类,请手动更新您正在跟踪的类或模块的
\uuuuuuuuuuuuuuu


有关更多信息,请参阅。

您需要在类上创建一个静态列表,并向每个实例添加一个
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)

非常好而且有用的代码,但它有一个大问题:列表总是更大,而且从来没有清理过,要测试它,只需在
get\u实例
方法的末尾添加
print(len(cls.\uu refs\uu[cls])

下面是对
get\u实例
方法的修复:

__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]

你不需要导入任何东西!只需使用“self”即可。以下是你的操作方法

class A:
    instances = []
    def __init__(self):
        self.__class__.instances.append(self)

    @classmethod
    def printInstances(cls):
        for instance in cls.instances:
            print(instance)
A.printInstances()

就是这么简单。在我的项目中没有导入任何模块或库,我遇到了类似的问题,并找到了一个简单的解决方案,该解决方案在列出和打印类实例时可能也适用。该解决方案在Python 3.7版中运行顺利;在Python 3.5版中出现了部分错误

我将复制粘贴我最近项目中的相关代码块

```
instances = [] 

class WorkCalendar:
    def __init__(self, day, patient, worker):
        self.day = day
        self.patient = patient
        self.worker= worker
    def __str__(self):
        return f'{self.day} : {self.patient} : {self.worker}'
在Python中,
\uuu str\uu
方法最终决定了如何以字符串形式解释对象。我在花括号之间添加了
,它们完全是我对“熊猫数据帧”的偏好这是一种阅读。如果你应用这个小的
\uuuuu str\uuuuuuu
函数,你将看不到一些机器可读的对象类型描述——这对人眼来说毫无意义。添加这个
\uuuuuu str\uuuuu
函数后,你可以将对象附加到列表中,并按你的意愿打印它们

appointment= WorkCalendar("01.10.2020", "Jane", "John")
instances.append(appointment)
打印时,
\uuu str\uu
中的格式将作为默认格式。但也可以单独调用所有属性:

for instance in instances:
    print(instance)
    print(instance.worker)
    print(instance.patient)

详细阅读时,您可以查看源代码:

这是一个令人困惑的问题。您想要一个格式都相似的方法函数吗?还是想要一个包含所有实例的集合?尝试对类的所有实例执行某些操作几乎总是一个错误,这表明您还不习惯组织对象使用正确的数据结构,正确的操作类似于“使用此数据结构的所有元素执行[thing],而不是“使用此类的所有实例执行[thing]”。不完全正确。有些语言提供对其对象内存的访问。在这些语言中,例如Smalltalk和Ruby,您可以查询一个类的所有实例。(实际上,我很惊讶Python没有提供这一功能。)@阿德里安·库恩:请看@NXC关于Smalltalk的allInstances功能的帖子。也许Ruby是最后一个坚持的人?我个人不希望看到解释器总是承担额外的开销,总是提供一些并不总是需要的东西,特别是当它——正如所演示的那样——很容易实现的时候垃圾收集器很有趣,但对于这种类型的应用程序可能没有那么大的用处。我知道,但如果其他一切都失败了,它是最后的手段。也许我应该把它作为选项2。在我看来,OP询问的是方法。您将如何扩展它以包括子类的实例?因为Python 2.7可以使用一个更简单的方法来完成这项工作。感谢nice,但它只适用于您创建的类。如果您要对从现有包导入的类执行此操作,您必须使用此功能来包装它们。这是可行的,但您必须e您的整个代码使用您的包装器类而不是原始类实例化它们。您可以使用
print('\n'.join(A.instances))
?这样,您就不需要创建方法
printInstance
。是否可以在不使用weakref或任何其他特殊模块的情况下打印所有类实例?如果写入“self.name=name\n self.\uu\c
appointment= WorkCalendar("01.10.2020", "Jane", "John")
instances.append(appointment)
for instance in instances:
    print(instance)
    print(instance.worker)
    print(instance.patient)