一文搞懂python2/3 from __future__ import absolute_import

干货

  • 当py文件作为模块被调用的时候,可以直观的看出导入和未导入absolute_import的效果差别
  • py文件(例如a.py)作为模块被调用的情况可以是
    1. 在其他py文件导入import a
    2. 通过python -m xxx.yyy 其中xxx是某个python的package, yyy是package下的某个模块
  • absolute_import的作用是改变模块导入的顺序,当某个py文件没有使用absolute_import的时候,py文件优先导入和自己同级的模块,然后再导入注册的模块以及系统模块。当使用absolute_import的时候,优先导入的是注册已经系统模块。
  • xxx作为package,需要其目录下有__init__.py文件。文件内容可以为空

例子

目录结构如下

|- demo
    | - pkg
        | -- __init__.py
        | -- main.py
        | -- numpy.py

其中numpy.py和__init__.py内容都为空,main.py的内容如下:

from __future__ import print_function
from __future__ import absolute_import
import sys
import numpy as np
print(sys.path)
print(np.array([0]))

当我们在demo目录下,即和pkg文件夹同级的目录下运行python脚本, 即

python -m pkg.main

得到如下结果

['', 'D:\\python3.5\\python36.zip', 'D:\\python3.5\\DLLs', 'D:\\python3.5\\lib', 'D:\\python3.5', 'D:\\python3.5\\lib\\site-packages', 'D:\\python3.5\\lib\\site-packages\\win32', 'D:\\python3.5\\lib\\site-packages\\win32\\lib', 'D:\\python3.5\\lib\\site-packages\\Pythonwin'] 
[0]

其中第一个list就是sys.path, 也就是该py文件寻找库的路径。注意:这里是pkg.main

有图有真相
一文搞懂python2/3 from __future__ import absolute_import_第1张图片

但是假如我们直接调用即还是在原来的地方执行

python pkg\main.py

得到的结果是:

['E:\\demo\\pkg', 'D:\\python3.5\\python36.zip', 'D:\\python3.5\\DLLs', 'D:\\python3.5\\lib', 'D:\\python3.5', 'D:\\python3.5\\lib\\site-packages', 'D:\\python3.5\\lib\\site-packages\\win32', 'D:\\python3.5\\lib\\site-packages\\win32\\lib', 'D:\\python3.5\\lib\\site-packages\\Pythonwin']
Traceback (most recent call last):
  File "pkg\main.py", line 6, in 
    print(np.array([0]))
AttributeError: module 'numpy' has no attribute 'array'

有图有真相
一文搞懂python2/3 from __future__ import absolute_import_第2张图片

可以看到在这次的结果中,第一个list的第一个路径是demo\pkg, 也就是运行脚本的路径。换句话说,直接调用某py文件, 会将该py文件所在的同级目录添加到sys.path的top_level, 而在模块调用时候就不会添加。因此当你通过直接调用的方式(即直接调用python yyy.py)的时候,并不能检验出引入还是没有引入absolute_import模块的区别。同时这也解释了,当a.py模块被调用,同时a.py模块与调用的py文件不在同级目录,并且a.py模块需要调用与自己(a.py)同级目录模块,需要在a.py文件下显示的将a.py同级目录添加到sys.path中。即

sys.path.append(os.path.dirname(os.path.abspath(__file__)))

资料

https://www.python.org/dev/peps/pep-0328/

你可能感兴趣的:(python)