打印类的所有实例

use*_*061 56 python class

使用Python中的类,如何定义一个函数以函数中定义的格式打印类的每个单个实例?

Tor*_*rek 87

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

垃圾收集器

import gc
for obj in gc.get_objects():
    if isinstance(obj, some_class):
        dome_something(obj)
Run Code Online (Sandbox Code Playgroud)

这样做的缺点是,当你拥有大量对象时速度非常慢,但是使用你无法控制的类型.

使用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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,所有引用都存储为列表中的弱引用.如果你经常创建和删除很多实例,你应该在迭代后清理weakrefs列表,否则会有很多错误.

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

编辑:根据特定格式打印所有实例的方法for留作练习,但它基本上只是-loops 的变体.


小智 23

您需要在类上创建静态列表,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)
Run Code Online (Sandbox Code Playgroud)

  • 是否可以在没有weakref或任何其他特殊模块的情况下打印所有类实例?如果写成“self.name = name\n self.__class__.instances.append(name)\n”会发生什么? (2认同)

Или*_*иев 18

你不需要导入任何东西!只需使用“自我”。这是你如何做到这一点

class A:
    instances = []
    def __init__(self):
        self.__class__.instances.append(self)
print('\n'.join(A.instances)) #this line was suggested by @anvelascos
Run Code Online (Sandbox Code Playgroud)

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

  • 是否可以使用“print('\n'.join(A.instances))”?这样,您就不需要创建“printInstance”方法。 (2认同)

S.L*_*ott 6

与几乎所有其他 OO 语言一样,将类的所有实例保存在某种集合中。

你可以试试这种东西。

class MyClassFactory( object ):
    theWholeList= []
    def __call__( self, *args, **kw ):
         x= MyClass( *args, **kw )
         self.theWholeList.append( x )
         return x
Run Code Online (Sandbox Code Playgroud)

现在你可以这样做了。

object= MyClassFactory( args, ... )
print MyClassFactory.theWholeList
Run Code Online (Sandbox Code Playgroud)

  • 不完全正确。某些语言提供对其对象内存的访问。在这些语言中,例如 Smalltalk 和 Ruby,您可以查询一个类的所有实例。(实际上,我很惊讶 Python 也没有提供。) (4认同)
  • 我个人宁愿不看到解释器总是提供一些并不总是需要的东西,特别是当它 - 正如所展示的 - 当它很容易实现时,会遭受额外的开销。 (2认同)

Fab*_*amo 6

非常好的代码和有用的代码,但是有一个大问题:列表总是更大,并且永远不会被清除,要测试它,只需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
Run Code Online (Sandbox Code Playgroud)

或者,也可以使用WeakSet完成:

from weakref import WeakSet

__refs__ = defaultdict(WeakSet)

@classmethod
def get_instances(cls):
    return cls.__refs__[cls]
Run Code Online (Sandbox Code Playgroud)