Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Dynamic class import

I have the following folder structure:

- MyProject
    - App1
        - some_module1.py
        - some_module2.py
    - App2
        - some_other_module1.py
        - some_other_module2.py

Inside each of the modules (some_module1.py for example) there is a class that extends from a base class, in my case, Producer.

What I am trying to do is dynamically load in this class. To do that, I have a list of "installed apps" that looks like this:

INSTALLED_APPS = (
    'App1',
    'App2',
)

I am trying to write a function that will check each "app" package for a particular producer class and ensure it extends from the producer base class. Something like this:

module_class = 'some_module1.SomeClass'

# Loop through each package in the INSTALLED_APPS tuple:
for app in INSTALL_APPS:
    try:
        #is the module_class found in this app?
        #App1.some_module1.SomeClass - Yes
        #App2.some_module1.SomeClass - No

        # is the class we found a subclass of Producer?
    exception ImportError:
        pass

I've tried experimenting with imp and importlib, but it doesn't seem to handle this kind of import. Is there anyway for me to be able to achieve this?

like image 1000
Hanpan Avatar asked Nov 09 '11 16:11

Hanpan


1 Answers

You may want to have a look at:

  • __import__() to import modules knowing their name as string;
  • dir() to get the names of all the objects of a module (attributes, functions, etc);
  • inspect.isclass(getattr(<module ref>, <object name>)) to identify classes among the objects of a module;
  • issubclass() to identify sub-classes from a given class, as explained here.

With these tools, you can identify all classes in a given module, that are inheriting a given class.

I'm using this mechanism to dynamically instantiate classes from given module, so that their updates are automatically taken into account at an upper level.

like image 182
Joël Avatar answered Oct 10 '22 06:10

Joël