关于Python导入的澄清

时间:2016-08-12 18:49:21

标签: python python-import

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

就Python命名空间和范围而言,有什么区别吗?如果您想使用bar中的某些内容(比如名为whatever的函数),则可以使用任一方法将其称为bar.whatever()

我在我正在使用的代码库中看到了两种导入样式,并且想知道它们带来了什么差异,如果有的话,以及更多的“Pythonic”方法。

2 个答案:

答案 0 :(得分:5)

当bar不是模块时,存在巨大差异:

# foo.py
bar = object()

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

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

答案 1 :(得分:4)

如果bar包中包含foo模块或包,并且bar 根本不是模块

考虑以下foo包:

foo/
    __init__.py
    bar.py

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

但是,一旦导入foo.bar模块,Python导入机制将在bar包中设置名称foo,替换任何预先存在的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绑定到某些内容,无论是模块中的对象还是模块对象。