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