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

前端 未结 2 1359
粉色の甜心
粉色の甜心 2021-01-04 01:15

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 skimag         


        
相关标签:
2条回答
  • 2021-01-04 01:55

    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.

    0 讨论(0)
  • 2021-01-04 01:58

    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.

    0 讨论(0)
提交回复
热议问题