Python module import - why are components only available when explicitly imported?

22,958

Solution 1

Quick answer: IO is a submodule. Submodules need to be imported from the parent module explicitly.

Long answer: From section 5.4.2 of the python docs:

When a submodule is loaded using any mechanism (e.g. importlib APIs, the import or import-from statements, or built-in import()) a binding is placed in the parent module’s namespace to the submodule object. For example, if package spam has a submodule foo, after importing spam.foo, spam will have an attribute foo which is bound to the submodule. Let’s say you have the following directory structure:

spam/
    __init__.py
    foo.py
    bar.py

and spam/init.py has the following lines in it:

from .foo import Foo
from .bar import Bar

then executing the following puts a name binding to foo and bar in the spam module:

>>>
>>> import spam
>>> spam.foo
<module 'spam.foo' from '/tmp/imports/spam/foo.py'>
>>> spam.bar
<module 'spam.bar' from '/tmp/imports/spam/bar.py'>

Given Python’s familiar name binding rules this might seem surprising, but it’s actually a fundamental feature of the import system. The invariant holding is that if you have sys.modules['spam'] and sys.modules['spam.foo'] (as you would after the above import), the latter must appear as the foo attribute of the former.

Solution 2

It's simply the way Python handles modules.

One reason is that it would make importing one module very slow if cpython needed to scan for submodules, import all of them and then import all of their submodules.

The other reason is "better be explicit than implicit". Why should Python import everything possible when you only need a small fraction of a package with a complex module hierarchy.

Instead of from skimage import io you can also write

import skimage.io

then skimage.io.imread will be found.

Share:
22,958
jmsinusa
Author by

jmsinusa

Deep learning researcher, particularly interested in Intelligence Video Analytics (IVA) and geospatial data.

Updated on July 27, 2022

Comments

  • jmsinusa
    jmsinusa almost 2 years

    I have recently installed scikit-image version 0.11.3. I am using python 2.7.10. When I import the entire module I cannot access the io module.

    import skimage
    img = skimage.io.imread(path_)
    

    Gives error:

    AttributeError: 'module' object has no attribute 'io'
    

    However the following does not error.

    from skimage import io
    img = io.imread(path_)
    

    Question: Why?