Issue
I'm playing around with matplotlib to understand its structure better and I'm confused by the following piece of code:
import matplotlib as mpl
from mpl import pyplot as plt # ModuleNotFoundError : No module named 'mpl'
mpl.pyplot # AttributeError: module 'matplotlib' has no attribute 'pyplot'
If on the other hand I abstain from importing matplotlib as
a different name and execute instead
import matplotlib
from matplotlib import pyplot as plt #works!
the things work.
Even more crazy, if I "combine" these two import matplotlib as mpl from matplotlib import pyplot as plt #works! mpl.pyplot.get_backend() # works
I can curiously access attributes from pyplot
even if I reference it as mpl.pyplot
.
What is going on here, why does
from mpl import pyplot as plt
throws aModuleNotFoundError
?import mpl.pyplot
not work? Since the error message indcates thatmpl
was correctly resolved tomatplotlib
, yet stillpyplot
couldn't be found...referencing
pyplot
asmpl.pyplot
not cause an error in my last example?
(Note that I do know of course that the preferred way is to import pyplot
as import matplotlib.pyplot as plt
but the point of my investigation is precisely to understand what fails and why when I ventured outside the welltrodden streets of code.)
Solution
The as
part in an import statement is just syntactic sugar for assigning the imported module to a variable with the given name. The import
documentation describes it as such:
If the module name is followed by as, then the name following as is bound directly to the imported module.
"Bound" in this context means doing an assignment to the given name. The following statement
import someModule as someName
Is equivalent to this code:
import someModule
someName = someModule
So, when you do import matplotlib as mpl
, all you do is create a variable called mpl
. This has no effect on any further import statements, as import statements do not care about your local variables, but search for python packages and modules - and an import as
statement cannot change the package or module name of the imported element. Which is a good thing, as you do not want your import statements to fail just because another import 5 lines earlier used a conflicting name in an as
clause.
Now, why you're getting weird results with the import mpl.pyplot
statement - no idea, it shouldn't work. You can see the expected behaviour if you try the following:
import os as asdf
import asdf.path #ModuleNotFoundError: no module named 'asdf'
Tested with python 3.10.2 on Archlinux. If your example is reproducible, then you might have found a weird bug or undefined behaviour in your specific python version, or have some other issue (e.g. a mpl
module in your path... although that on its own wouldn't explain why you get an error message about matplotlib instead of mpl).
In conclusion, all as
does is assigning a name to the imported object, so a name assigned with as
cannot be used as a source in another import statement.
On package imports and why matplotlib.pyplot
gives an error:
Importing a package only imports the package itself, not any of its subpackages or modules. A package can explicitly import submodules in its __init__.py
, so if the matplotlib init file would contain a statement like from . import pyplot
line then accessing matplotlib.pyplot
would work. There are however many reasons why a package might choose not to import any submodules, such as time and resources required to import and initialize them.
Answered By - l4mpi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.