Search code examples
pythonwindowspython-3.xpython-importpython-module

Dynamic module import in python (code from 3.2 to 3.3)


I need to dynamically import a module and create a class.
This is my working code in Python 3.2:

klass = {}
mod = __import__('sites.' + self.className + '_login', fromlist=[self.className])
klass[self.className] = getattr(mod, self.className)
klass[self.className](**self.args)

The module is inside the sites folder. It's called my_site_login and the class within that module my_site.

Since I upgrade to Python 3.3, the code stopped working. I read that _____import_____ was replace by importlib.import_module. I tried several ways to do it but I can't get it to work.

This is what I tried:
https://stackoverflow.com/a/8790051/1095101

mod = getattr(import_module('sites.' + self.className + '_login'), self.className)

I can't remember what else I've tried. What I can say, is that none of the print() I put right after any import attempt, was showing. I don't get any error message. It just does nothing.


Solution

  • You want to restructure this; in the sites package __init__.py file, import all modules that need to be imported dynamically.

    Then just use attribute access instead:

    import sites
    
    mod = getattr(sites, self.className + '_login')
    klass[self.className] = getattr(mod, self.className)
    klass[self.className](**self.args)
    

    If your my_site_login.py modules are dynamically generated, the importlib.import_module() callable works very simply:

    importlib
    
    mod = importlib.import_module('sites.{}_login'.format(self.className))
    klass[self.className] = getattr(mod, self.className)
    klass[self.className](**self.args)
    

    From the interactive command prompt this works fine:

    >>> import importlib
    >>> importlib.import_module('sites.my_site_login')
    <module 'sites.my_site_login' from './sites/my_site_login.py'>
    

    Tested that in Python 2.7, 3.2 and 3.3.