Python: "import ... as" causes incorrect reference
Solution 1
Why do you expect it to work? All 4 of your import statements are assignments to the variable a
. Thus if you assign c
to a
, it overwrites the contents with something that doesn't have a .b
attribute.
Here's what happens in the first case:
- When
import a.b
is run, Python loads modulea
, and then loads the modulea.b
into the loadeda
module's attributeb
. It then assigns the result to the variablea
. - The
import a
doesn't import anything new, because modulea
is already loaded. It simply reassigns the same module fromsys.modules['a']
toa
.
Here's what happens in the second case:
- When
import a.b
is run, Python loads modulea
, and then loads the modulea.b
into the loadeda
module's attributeb
. It then assigns the result to the variablea
. - When
import c as a
is run, it loads the modulec
, and then assigns that module to variablea
, overwriting the contents (a = sys.modules['c']
). You could verify this by comparing the contents ofsys.modules['a']
with the contents ofa
- they'll be different in this case.
Solution 2
if you import c as a
it will overwrite your previous a
so if you try to call a.b
you really call c.b
Solution 3
In the first case, a
refers to the actual package a
(which contains the module b
). This means that a.b
refers to something which is contained by a
.
In the second case, a
refers to module c.py
. It's as though you tried import c; a = c
. Now, if c
doesn't have an attribute b
, it will fail.
Solution 4
When you do an "import as" statement, you are really doing an assignment. So if you do this
import matplotlib as mp
you are assigning the namespace for matplotlib
to mp
.
That carries all of the usual implications of assignment.
Admin
Updated on June 04, 2022Comments
-
Admin almost 2 years
I've noticed a peculiar behavior in how python handles module names.
If I write:
import a.b import a
and then attempt to reference something in module a.b, it works without a problem.
However, if I attempt something only slightly different:
import a.b import c as a
and then attempt to reference something in module a.b, I get an error, saying:
AttributeError: 'module' object has no attribute 'b'
I understand that the obvious solution is simply to not have two different modules I refer to by the same name. However, I'm still curious what caused this change in behaviour. Why does one work and not the other?
-
Admin over 11 yearsThis makes a lot of since. I've been using java recently, so I considered "a" and "a.b" to be separate from each other. It's didn't occur to me that modules were being stored as objects and that I was overwriting them. Thank you.