8

Is there a way to initialize all classes from a python module into a list of nameless objects?

Example I have a module rules which contains all child classes from a class Rule. Because of that, I'm certain they will all implement a method run() and will have a attribute name which will be generated during the call of __init__

I would like to have a list of objects dynamically initiated from those classes. By dynamically initialized i mean that they don't have to be named explicitly.

The questions are:

Is it possible to iterate through all classes in a module?

Can a nameless object be initiated?

TheMeaningfulEngineer
  • 15,679
  • 27
  • 85
  • 143

1 Answers1

9

There are at least two approaches you can take. You can get all of the subclasses of a class by calling a class's __subclasses__() method. So if your parent class is called Rule, you could call:

rule_list = [cls() for cls in Rule.__subclasses__()]

This will give you all subclasses of Rule, and will not limit them to the ones found in a particular module.

If you have a handle to your module, you can iterate over its content. Like so:

import rule
rule_list = []
for name in dir(rule):
    value = getattr(rule, name)
    if isinstance(value, type) and issubclass(value, Rule):
        rule_list.append(value())

Unfortunately, issubclass throws TypeError if you give it an object that is not a class as its first argument. So you have to handle that somehow.

EDIT: dealing with the issubclass quirk per @Blckknght's suggestion.

Matt Anderson
  • 19,311
  • 11
  • 41
  • 57
  • 1
    Better than my answer. You can use `inspect.isclass()` to avoid the `TypeError`. – Antonis Christofides Aug 19 '13 at 15:10
  • 1
    @AntonisChristofides True, you can use `inspect.isclass()` as a filter. I try to avoid using anything from the `inspect` module in production code, however. – Matt Anderson Aug 19 '13 at 15:15
  • 1
    You can also use `isinstance(value, type)` to make sure you have a class. (You'd also need to check for `types.ClassType` if you need to support old-style classes, but I'd just avoid those instead.) – Blckknght Aug 20 '13 at 03:24