Printing all instances of a class

With a class in Python, how to define a function to print each individual instance of a class in the format defined in the function?

+53
python class
Nov 30 '08 at 13:23
source share
8 answers

In this case, I see two options:

Garbage collector

import gc for obj in gc.get_objects(): if isinstance(obj, some_class): dome_something(obj) 

This has the disadvantage of being very slow when you have many objects, but it works with types that you have no control over.

Use mixin and 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 

In this case, all links are obtained as a weak link in the list. If you often create and delete many instances, you must clear the list of weaknesses after iteration, otherwise there will be a lot of toughness.

Another problem in this case is that you must definitely call the base class constructor. You can also override __new__ , but only the __new__ method of the first base class is used to instantiate. It also only works on types that are under your control.

Change The method of printing all the copies in accordance with a specific format remains in the form of an exercise, but basically it is a variation on for -loops.

+85
Nov 30 '08 at 13:56
source share

You want to create a static list in your class and add weakref to each instance so that the garbage collector can clean up your instances when they are 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) 
+22
Feb 27 '12 at 4:26
source share

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

Here is the 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, this can be done using WeakSet:

 from weakref import WeakSet __refs__ = defaultdict(WeakSet) @classmethod def get_instances(cls): return cls.__refs__[cls] 
+5
Apr 27 '18 at 13:56
source share

Like all other OO languages, save all instances of the class in a collection.

You can try such things.

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

Now you can do it.

 object= MyClassFactory( args, ... ) print MyClassFactory.theWholeList 
+3
Nov 30 '08 at 13:29
source share

Python does not have the equivalent of Smallktalk #allInstances, since there is no such table of central objects in the architecture (although modern small lines do not work either).

As another poster says, you must explicitly manage the collection. His suggestion of a factory method that supports the registry is a perfectly reasonable way to do this. You might want to do something with weak links so that you do not have to explicitly track the removal of objects.

+3
Nov 30 '08 at 13:57
source share

Perhaps you mean something like __str__ :

 object.__str__(self) 

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

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 >>> 
+1
Nov 30 '08 at 13:34
source share

It is not clear whether to print all instances of the class at once or when they are initialized, or if you are talking about the class that you have above the class in a third-party library.

In any case, I would solve this by writing a factory class using Python metaclass support. If you do not have class control, manually update __metaclass__ for the monitored class or module.

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

+1
Nov 30 '08 at 20:55
source share

You do not need to import ANYTHING! Just use the "I". This is how you do it

 class A: instances = [] def __init__(self): self.__class__.instances.append(self) @classmethod def printInstances(cls): for instance in cls.instances: print(instance) A.printInstances() 

It is so simple. No imported modules or libraries

0
Jul 02 '19 at 9:13
source share



All Articles