Search code examples
pythonpython-import

Importing module from string variable using "__import__" gives different results than a normal import statement


I'm working on a documentation (personal) for nested matplotlib (MPL) library, which differs from MPL own provided, by interested submodule packages. I'm writing Python script which I hope will automate document generation from future MPL releases.

I selected interested submodules/packages and want to list their main classes from which I'll generate list and process it with pydoc.

The problem is that I can't find a way to instruct Python to load a submodule from a string. Here is an example of what I tried:

import matplotlib.text as text
x = dir(text)
i = __import__('matplotlib.text')
y = dir(i)
j = __import__('matplotlib')
z = dir(j)

And here is a 3-way comparison of above lists through pprint:

enter image description here

I don't understand what's loaded in y object - it's base matplotlib plus something else, but it lacks information that I wanted and that is main classes from matplotlib.text package. It's the top blue coloured part on screenshot (x list).


Solution

  • The __import__ function can be a bit hard to understand.

    If you change

    i = __import__('matplotlib.text')
    

    to

    i = __import__('matplotlib.text', fromlist=[''])
    

    then i will refer to matplotlib.text.

    In Python 3.1 or later, you can use importlib:

    import importlib
    
    i = importlib.import_module("matplotlib.text")
    

    Some notes

    • If you're trying to import something from a sub-folder e.g. ./feature/email.py, the code will look like importlib.import_module("feature.email")

    • Before Python 3.3 you could not import anything if there was no __init__.py in the folder with file you were trying to import (see caveats before deciding if you want to keep the file for backward compatibility e.g. with pytest).