Listing all instance of a class

旧街凉风 提交于 2021-02-17 06:47:08

问题


I wrote a Python module, with several classes that inherit from a single class called MasterBlock. I want to import this module in a script, create several instances of these classes, and then get a list of all the existing instances of all the childrens of this MasterBlock class. I found some solutions with vars()['Blocks.MasterBlock'].__subclasses__() but as the instances I have are child of child of MasterBlock, it doesn't work.

Here is some example code:

Module:

Class MasterBlock:
    def main(self):
        pass
Class RandomA(MasterBlock):
    def __init__(self):
        pass
    # inherit the main function
Class AnotherRandom(MasterBlock):
    def __init__(self):
        pass
    # inherit the main function

Script:

import module
a=module.RandomA()
b=module.AnotherRandom()
c=module.AnotherRandom()
# here I need to get list_of_instances=[a,b,c]

Th ultimate goal is to be able to do:

for instance in list_of_instances:
    instance.main()

回答1:


If you add a __new__() method as shown below to your base class which keeps track of all instances created in a class variable, you could make the process more-or-less automatic and not have to remember to call something in the __init__() of each subclass.

class MasterBlock(object):
    instances = []
    def __new__(cls, *args, **kwargs):
        instance = super(MasterBlock, cls).__new__(cls, *args, **kwargs)
        instance.instances.append(instance)
        return instance

    def main(self):
        print('in main of', self.__class__.__name__)  # for testing purposes

class RandomA(MasterBlock):
    def __init__(self):
        pass
    # inherit the main function

class AnotherRandom(RandomA):  # works for sub-subclasses, too
    def __init__(self):
        pass
    # inherit the main function

a=RandomA()
b=AnotherRandom()
c=AnotherRandom()

for instance in MasterBlock.instances:
    instance.main()

Output:

in main of RandomA
in main of AnotherRandom
in main of AnotherRandom



回答2:


What about adding a class variable, that contains all the instances of MasterBlock? You can record them with:

Class MasterBlock(object):

    all_instances = []  # All instances of MasterBlock

    def __init__(self,…):
        …
        self.all_instances.append(self)  # Not added if an exception is raised before

You get all the instances of MasterBlock with MasterBlock.all_instances (or instance.all_instances).

This works if all base classes call the __init__ of the master class (either implicitly through inheritance or explicitly through the usual super() call).




回答3:


Here's a way of doing that using a class variable:

class MasterBlock(object):
    instances = []
    def __init__(self):
        self.instances.append(self)
    def main(self):
        print "I am", self

class RandomA(MasterBlock):
    def __init__(self):
        super(RandomA, self).__init__()
        # other init...

class AnotherRandom(MasterBlock):
    def __init__(self):
        super(AnotherRandom, self).__init__()
        # other init...


a = RandomA()
b = AnotherRandom()
c = AnotherRandom()
# here I need to get list_of_instances=[a,b,c]

for instance in MasterBlock.instances:
    instance.main()

(you can make it simpler if you don't need __init__ in the subclasses)

output:

I am <__main__.RandomA object at 0x7faa46683610>
I am <__main__.AnotherRandom object at 0x7faa46683650>
I am <__main__.AnotherRandom object at 0x7faa46683690>


来源:https://stackoverflow.com/questions/30298350/listing-all-instance-of-a-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!