Loading classes from modules with reflection in Python (imp module)
23 Apr 2014
For a dynamic language, it's more difficult than it needs to be to import a module dynamically in Python. It's very easy to just from foo import bar, but what if you want to load a list of things and all you have is a string representation of each one, for example foo.bar?
One use case for this is for configuration. Django uses this pattern to initialize apps via its INSTALLED_APPS setting. For example, the default settings looks like this:
At some point, Django does the equivalent of a from django.contrib import admin and then starts poking around for urls and models modules. I'm guessing this is done primarily to avoid circular import issues; if Django imports your apps as normal, but your apps turn around and import Django, then you've got a problem.
I wanted to reproduce this pattern myself, and it was a little harder than I expected. Python provides an imp for just this occasion. But, from the docs:
This function does not handle hierarchical module names (names containing dots). In order to find P.M, that is, submodule M of package P, use findmodule() and loadmodule() to find and load package P, and then use findmodule() with the path argument set to P.path_. When P itself has a dotted name, apply this recipe recursively.
So, it's basically is a pain the balls to deal with. Here is a working example:
And the output as expected:
Here is a directory listing of my test modules, in case this isn't clear.
I'm currently working at NerdWallet, a startup in San Francisco trying to bring clarity to all of life's financial decisions. We're hiring like crazy. Hit me up on Twitter, I would love to talk.