1. 从查到的资料来看,关于import路径的来讲,分红3类:
import xml
import youpackage.xml
from youpackage import xml
这几种都算绝对路径
import xml
从这个语句上是看不出来import的是标准库的xml,仍是你的包里的一个库叫xml。
from . import xml
from .xml import some_thing
from ..xml import some_thing
这些以点开头的import明确的表示了import的是相对路径,从而避免了普通relative import的麻烦。
2. 第二种(relative import)确定是不推荐的。
- 在python2.5之前,若是当前包中有一个叫xml的库,局部的这个xml就会shadow标准库的xml(和局部变量感受相似,我犯过好几回这个错误,调试的时候还必定能反应过来)。
- 在2.5和2.6,这个行为仍是同样的,可是若是有如下这个语句,局部的包将不能覆盖全局的包
from __future__ import absolute_import
- 在2.7中,absolute_import的行为变成了默认行为,若是须要应用局部的包,那就得用明确的相对引用了。
文档是这么描述的,但经过-m运行和直接运行py的行为仍是会不同,看下面这个例子:
$ python --version
Python 2.6.5
$ cat bar/baz.py
from __future__ import absolute_import
import xml
print xml.__file__
$ python bar/baz.py
/home/huanghao/workspace/test/bar/xml.pyc
$ python -m bar.baz
/usr/lib/python2.6/xml/__init__.pyc
看上去很奇怪,经过py运行的时候absolute_import好像根本没有做用,缘由在这个blog里有解释
3.因此说relative import麻烦事太多,必定不能用了。可是absolute和explicit relative这两个到底用哪一个?
PEP8中提到:
Relative imports for intra-package imports are highly discouraged. Always use the absolute package path for all imports. Even now that
PEP 328
is fully implemented in Python 2.5, its style of explicit relative imports is actively discouraged; absolute imports are more portable and usually more readable.
PEP8仍是建议用absolute,即便PEP328实现了explicit relative。
原本我以为到此就为止了。
可是今天仍是有同事非要用explicit relative import,跟我说由于absolute写起来太长,并且当顶层包重命名时,全部的文件都须要修改。
我搜了半天也没找到有文章提到abs比rel必定要好的理由,除了PEP8提到的两个缺少说服力的词more portable and more readable。
4.explicit relative import有一个小问题:
Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main__') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.
Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always
"__main__"
, modules intended for use as the main module of a Python application should always use absolute imports.
虽然PEP338搞定了explicit relative import 在-m执行时的问题,可是搞不定直接文件执行的状况。因此用来作程序入口的模块必须使用绝对引用。
看一下这个例子:
$ python --version
Python 2.6.5
$ cat bar/baz.py
from . import xml
print xml.__file__
$ python -m bar.baz
bar/xml.pyc
$ python bar/baz.py
Traceback (most recent call last):
File "bar/baz.py", line 1, in <module>
from . import xml
ValueError: Attempted relative import in non-package