0

Let's say I have a superclass Spam, and from it there's a lot of subclasses. How do I look through all instances in the entire runtime of one of these and reference them for data manipulation or comparisons? Doesn't have to be about superclasses and subclasses specifically, but I wanted to mention those in case there's different approaches between those and independent classes.

It seems like a pretty core question in Python programming, but I couldn't find any information that answers what I look for specifically, oddly enough, unless I am using the wrong terms.

Holsterbau
  • 87
  • 1
  • 7
  • 1
    This [answer](https://stackoverflow.com/a/328882/2089675) could be useful – smac89 Mar 08 '18 at 23:55
  • @smac89 Ah, considering I wish to create many classes, `weakref` does indeed look like a correct application of what I want to accomplish. Thanks. – Holsterbau Mar 09 '18 at 00:16
  • 1
    Another similar question is [here](https://stackoverflow.com/questions/12101958/how-to-keep-track-of-class-instances). – Blckknght Mar 09 '18 at 03:32

1 Answers1

1

You can keep track of all instances that are still referenced using a WeakSet.

from weakref import WeakSet

class Spam:
    _instances = WeakSet()

    def __init__(self, *args, **kwargs):
        self._instances.add(self)

Here is a working example.

class SubSpam(Spam):
    pass

x = SubSpam() # Create an instance

len(Spam._instances) # 1

x = 0 # Drop reference to this instance

len(Spam._instances) # 0

For the above to work you will need to make sure to always call the super __init__ method when overidding __init__.

class AnotherSubSpam(Spam):
    def __init__(self):
        # Do some stuff
        super().__init__()

Alternatively, you could also keep track of the instances in the __new__ method which is not as often overridden.

class Spam:

    _instances = WeakSet()

    def __new__(cls, *args, **kwargs):
        # Create the instance
        instance = super().__new__(cls, *args, **kwargs)

        # Keep track of the instance
        cls._instances.add(instance)

        # Return the instance as __new__ would
        return instance
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73