Reputation: 13254
Assume you have a package foo
with the following __init__.py
:
from bar import *
With bar
being any python module installed with pip install bar
.
Now what always works when you can import bar
:
from bar import submodule #works
import bar.submodule #works, too
Now I would assume the following things would all work as well:
from foo import submodule # a) is possible
import foo.submodule # b) not possible ("no module named submodule")
from foo.bar import submodule # c) also impossible ("no module named submodule")
Why are they not possible? What would I need to do to make them possible, from the point of view of the foo
maintainer?
Upvotes: 2
Views: 84
Reputation: 26160
submodule
and bar
are members of the foo
module object, not submodules of it. Therefore, they behave just like any other member attribute of foo
. You can bring them into the module namespace of a third module with the from foo import ...
form, but you can't directly import
them relative to foo
. I guess you could if you hacked them in to sys.modules
under the desired name manually, but you really shouldn't be doing anything like that...
To illustrate the issue:
foo.py
# x and y are values in the foo namespace, available as member attributes
# of the foo module object when foo is imported elsewhere
x = 'x'
y = 'y'
bar.py
# the foo module object is added as a member attribute of bar on import
# with the name foo in the bar namespace
import foo
# the same foo object is aliased within the bar namespace with the name
# fooy
import foo as fooy
# foo.x and foo.y are referenced from the bar namespace as x and y,
# available as member attributes of the bar module object
from foo import x, y
# z is a member attribute of the bar module object
z = 'z'
baz.py
# brings a reference to the x, y, and z attributes of bar (x and y
# come in turn from foo, though that's not relevant to the import;
# it just cares that bar has x, y, and z attributes), in to the
# namespace of baz
from bar import x, y, z
# won't work, because foo is a member of bar, not a submodule
import bar.foo
# will work, for the same reason that importing x, y, and z work
from bar import foo
Upvotes: 2