Dynamic class loading in Python 2.6: RuntimeWarning: Parent module 'plugins' not found while handling absolute import
If the plugins directory does not have an __init__.py
, it isn't a package, so when you create plugins.whatever
, Python warns you that such a thing shouldn't really exist. (It couldn't be created by "import plugins.whatever
" no matter what your path is.)
Also,
- Don't split on
/
, which is unportable. Useos.path.split
. - Don't use
.split(".py")
to get the name without the extension, which is buggy. Useos.path.splitext
. - Don't use
getattr
with a string literal.getattr(plugin, "__init__")
is spelledplugin.__init__
. - I am confused why you are calling a module-level
__init__
function. This doesn't seem right. Perhaps you want a "set_logger" function or better, to instantiate a class that takes a logger. - Don't use
L = L + some_other_list
to extend a list, use theextend
method, which has better performance and is more idiomatic. - Don't squash unknown exceptions by
except Exception
. If you cannot plan to do something sane in response to an exception, your program cannot go on sanely.
If the directory plugins
were a real package (contained __init__.py
fine), you could easily use pkgutils to enumerate its plugin files and load them.
import pkgutil# import our packageimport pluginslist(pkgutil.iter_modules(plugins.__path__))
However, it can work without a plugin package anyway, try this:
import pkgutillist(pkgutil.iter_modules(["plugins"]))
Also it is possible to make a package that only exists at runtime:
import typesimport sysplugins = types.ModuleType("plugins")plugins.__path__ = ["plugins"]sys.modules["plugins"] = pluginsimport plugins.testplugin
However that hack that was mostly for fun!
The problem here is with the dot ('.') in the module name:
imp.load_module('plugins.'+name, f, file, desc)
Don't include a '.' after 'plugins', or Python will think it's a module path.