关于 Python 进口的澄清

Clarification about Python imports

from foo import barimport foo.bar as bar有什么区别?

就Python 命名空间和作用域而言,有什么区别吗?如果你想使用来自 bar 的东西(比如一个名为 whatever 的函数),你可以使用任何一种方法将其称为 bar.whatever()

我在我正在使用的代码库中看到了两种导入方式,我想知道它们有什么区别(如果有的话),以及什么会被认为是更 "Pythonic" 的方法。

当 bar 不是模块时,有很大的不同:

# foo.py
bar = object()

这里 from foo import bar 在 python 中是正常的,但是 import foo.bar as bar 会引发 ImportError: No module named bar.

通常我们只使用 "as" 构造来为名称添加别名:为名称添加一些上下文以提高可读性,或者避免与其他名称发生冲突。

存在差异,当 bar 模块或包内有 foo 包时,如果 bar 不是模块全部.

考虑了以下 foo 软件包:

foo/
    __init__.py
    bar.py

如果__init__.py文件也定义了一个全局名称bar,那么第一个示例将导入那个对象.第二个例子将导入 bar.py 模块。

然而,一旦 foo.bar 模块被导入,Python 导入机制将在 foo 包中设置名称 bar,替换任何预先存在的bar 全局 __init__.py:

$ ls -1 foo/
__init__.py
bar.py
$ cat foo/__init__.py
bar = 'from the foo package'
$ cat foo/bar.py
baz = 'from the foo.bar module'
$ python
Python 2.7.12 (default, Aug  3 2016, 18:12:10)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from foo import bar
>>> bar
'from the foo package'
>>> import foo.bar as bar
>>> bar
<module 'foo.bar' from 'foo/bar.pyc'>
>>> bar.baz
'from the foo.bar module'
>>> from foo import bar
>>> bar
<module 'foo.bar' from 'foo/bar.pyc'>

另一种情况是没有 bar.py子模块。 foo 可以是一个包,也可以是一个简单的模块。在这种情况下 from foo import bar 将始终在 foo 模块中查找对象,而 import foo.bar as bar 将始终失败:

$ cat foo.py
bar = 'from the foo module'
$ python
Python 2.7.12 (default, Aug  3 2016, 18:12:10)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
>>> foo.bar
'from the foo module'
>>> from foo import bar
>>> bar
'from the foo module'
>>> import foo.bar as bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named bar

请注意,在导入成功的所有情况下,您最终都会得到一个绑定到 某物 的全局名称 bar,或者是来自模块的对象,或者是模块对象。