关于 Python 进口的澄清
Clarification about Python imports
from foo import bar
和import 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
,或者是来自模块的对象,或者是模块对象。
from foo import bar
和import 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
,或者是来自模块的对象,或者是模块对象。