Printing all instances of a class

2019-01-01 10:23发布

With a class in Python, how do I define a function to print every single instance of the class in a format defined in the function?

标签: python class
7条回答
长期被迫恋爱
2楼-- · 2019-01-01 10:56

Very nice and useful code, but it has a big problem: list is always bigger and it is never cleaned-up, to test it just add print(len(cls.__refs__[cls])) at the end of the get_instances method.

Here a fix for the get_instances method:

__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

or alternatively it could be done using WeakSet:

from weakref import WeakSet

__refs__ = defaultdict(WeakSet)

@classmethod
def get_instances(cls):
    return cls.__refs__[cls]
查看更多
琉璃瓶的回忆
3楼-- · 2019-01-01 11:01

Python doesn't have an equivalent to Smallktalk's #allInstances as the architecture doesn't have this type of central object table (although modern smalltalks don't really work like that either).

As the other poster says, you have to explicitly manage a collection. His suggestion of a factory method that maintains a registry is a perfectly reasonable way to do it. You may wish to do something with weak references so you don't have to explicitly keep track of object disposal.

查看更多
余生无你
4楼-- · 2019-01-01 11:04

It's not clear if you need to print all class instances at once or when they're initialized, nor if you're talking about a class you have control over vs a class in a 3rd party library.

In any case, I would solve this by writing a class factory using Python metaclass support. If you don't have control over the class, manually update the __metaclass__ for the class or module you're tracking.

See http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html for more information.

查看更多
泪湿衣
5楼-- · 2019-01-01 11:04

Maybe you mean something like __str__:

object.__str__(self)

Called by the str() built-in function and by the print statement to compute the “informal” string representation of an object. This differs from repr() in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead. The return value must be a string object.

A trivial example:

>>> class dummy(object):
...     def __init__(self):
...         pass
...     def __str__(self):
...         return "I am a dummy"
...     
>>> d1=dummy()
>>> d2=dummy()
>>> print d1,d2
I am a dummy I am a dummy
>>>
查看更多
闭嘴吧你
6楼-- · 2019-01-01 11:07

You'll want to create a static list on your class, and add a weakref to each instance so the garbage collector can clean up your instances when they're no longer needed.

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)
查看更多
与君花间醉酒
7楼-- · 2019-01-01 11:13

Same as almost all other OO languages, keep all instances of the class in a collection of some kind.

You can try this kind of thing.

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

Now you can do this.

object= MyClassFactory( args, ... )
print MyClassFactory.theWholeList
查看更多
登录 后发表回答