@songying
2018-11-08T10:54:29.000000Z
字数 1630
阅读 1108
python
也许你在初学python时看到过python导入的相关内容,无非是import ...
或 from ... import ...
,但是事实真的是这样吗,导入涉及到的东西远远不止这么点,下面听我一一叙来。
参考:
import sys # 导入整个模块
import sys as system # 导入整个模块并命名
from sys import ... # 导入sys模块中的子模块
from os import * # 不推荐,导入该模块下所有的包
from __future__ import ...
看到这个有没有一脸懵逼,当初我第一次遇到时,就感觉自己可能学的是假python。
__future__
模块由 PEP 236 提出并加入到 Python 2.1,其存在的主要原因是 Python 的版本升级经常会增加一些新的特性,而__future__
模块将一些新版本中将会增加的新的特性进行声明,同时使得旧版本可以使用这些新的语法特性。
这也就是说,如果你要想在低版本中使用高版本的特性,那么from __future__ import ...
可以很好的帮你实现,这也意味着如果你在你的代码中使用from __future__ import ...
, 会提高你代码的向下兼容性。
最后,强调两点:
- 如果你用的是 Python 2.1 以前的版本,是没办法使用
__future__
的。__future__
模块的导入一定要放在最上方,也就是在所有其它模块之前导入。
当你在你当年目录下建立的文件名或目录与标准库或其他第三方模块名冲突会怎么样?比如你在你的项目下建立一个sys
目录或sys.py
文件,当你导入import sys
会发生什么,到底是导入标准库文件,还是导入的是你新建立的文件? 答案是:导入的是你新建立的文件。
原因在于python的搜索路径,当你导入时,会按照以下路径按顺序来搜索你要导入的文件:
- 在当前目录下搜索该模块
- 在环境变量 PYTHONPATH 中指定的路径列表中依次搜索
- 在 Python 安装路径的 lib 库中搜索
- 也许会用到
.pth
文件,但一般不用
以上的搜索路径是有先后顺序的,如果我在当前目录下找到sys
模块,我就不会再去接着搜索了,这就意味着相同的模块名也许会带来灾难,这也是我强烈建议你不要命名与标准库或第三方库同名的文件。
python的搜索路径构成了sys.path
,如下图就是我的sys.path
:
sys.modules
: 已加载的模块信息python 所有加载的模块信息都存放在 sys.modules
结构中,当 import 一个模块时,会按如下步骤来进行
import A
,检查 sys.modules 中是否已经有 A,如果有则不加载,如果没有则为 A 创建 module 对象,并加载 Afrom A import B
,先为 A 创建 module 对象,再解析A,从中寻找B并填充到 A 的 __dict__
中包内导入就是包内的模块导入包内部的模块。举个例子:
example
--- main
--- test.py
--- model
--- view.py
这是常见的一个结构,将项目的不同模块区分开,那么此时的包内导入如何就是在test.py
中导入view.py
。
我个人理解与之相对应的是导入标准库模块或第三方模块。
首先,注意一点,绝对导入与相对导入是针对包内导入而言的。其中:
- 绝对导入的格式为:
import A.B
或from A import B
- 相对导入的格式为:
from .. import B
,.
代表当前模块,..
代表上层模块,...
代表上上层模块,依次类推。
from __future__ import absolute_import
这句话的意思是将所有导入视为绝对导入,指的是禁用
implicit relative import
(隐式相对导入), 但并不会禁掉explicit relative import
(显示相对导入)。