Python 模块导入 - 为什么组件仅在显式导入时可用? [英] Python module import - why are components only available when explicitly imported?

查看:57
本文介绍了Python 模块导入 - 为什么组件仅在显式导入时可用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近安装了 scikit-image 版本 0.11.3.我正在使用 python 2.7.10.当我导入整个模块时,我无法访问 io 模块.

导入skimageimg = skimage.io.imread(path_)

给出错误:

AttributeError: 'module' 对象没有属性 'io'

但是以下没有错误.

from skimage import ioimg = io.imread(path_)

问题:为什么?

解决方案

快速回答:IO 是一个子模块.子模块需要从父模块显式导入.

长答案:来自 python 文档的第 5.4.2 节:

当使用任何机制(例如 importlib API、import 或 import-from 语句或内置 import())加载子模块时,将在父模块的命名空间中放置一个绑定到子模块对象.例如,如果包 spam 有一个子模块 foo,那么在导入 spam.foo 后,spam 将有一个属性 foo 绑定到子模块.假设您有以下目录结构:

垃圾邮件/__init__.py文件酒吧.py

和 spam/init.py 中有以下几行:

from .foo import Foo从 .bar 导入栏

然后执行以下操作将名称绑定到垃圾邮件模块中的 foo 和 bar:

<预><代码>>>>>>>导入垃圾邮件>>>垃圾邮件<来自'/tmp/imports/spam/foo.py'的模块'spam.foo'>>>>垃圾邮件栏<来自'/tmp/imports/spam/bar.py'的模块'spam.bar'>

鉴于 Python 熟悉的名称绑定规则,这可能看起来令人惊讶,但它实际上是导入系统的一个基本特性.不变的是,如果你有 sys.modules['spam'] 和 sys.modules['spam.foo'](就像你在上面导入之后那样),后者必须作为前者的 foo 属性出现.

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?

解决方案

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.

这篇关于Python 模块导入 - 为什么组件仅在显式导入时可用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆