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