I am working on a text-based adventure game and have a module that has all of the action classes, e.g. Move(Action), Look(Action). I need a method of instantiating all of the classes in the module that are a subclass of the Action class into a list like this:
actions = [Move(), Look()]
Is there a way of doing this without having to individually instantiate the classes by typing their names?
This works:
class Action:
    pass
class Move(Action):
    pass
class Look(Action):
    pass
actions = []
global_objs = list(globals().items())
for name, obj in global_objs:
    if obj is not Action and isinstance(obj, type) and issubclass(obj, Action):
        actions.append(obj())
print(actions)
prints:
[<__main__.Move object at 0x101916ba8>, <__main__.Look object at 0x101916be0>]
First, we get all names an an object in the current module:
global_objs = list(globals().items())
We need to convert into a list because in Python 3  items() return a dictview object that reflects changes in the underlaying dictionary. Since we work in the same module, defining new objects will change this dictionary. Converting into a list solves this problem.
Next, we go through all objects. There are three conditions they need to fulfill to be subclass of Action:
obj is not Action- Since Action is a subclass of itself, we need filter it out.
isinstance(obj, type) - The object has to be a class. Otherwise, the test under 3. would not be possible. 
issubclass(obj, Action) - Finally, we can do our subclass test.
Now we can make instances of all filtered classes and append them to our list:
actions.append(obj())
If you are sure all classes are defined in one module or you even want all subclasses that are distributed over several modules, this would be much shorter:
>>> actions = [obj() for obj in Action.__subclasses__()]
>>> actions
[<__main__.Move at 0x10fc14fd0>, <__main__.Look at 0x10fc14668>]
                        from other_module import Action
def is_action_class(var):
    return var != Action and type(var) == type and issubclass(var, Action)
classes = []    
for attr in dir(my_module):
    var = getattr(my_module, attr)
    if is_action_class(var):
        classes.append(var)
instances = [c() for c in classes]
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With