在Python的大型項目中,一般都會用到模塊包來組織文件層次,其中當一個目錄內含有__init__ . py文件時,就可以視該目錄為一個模塊包。
當在模塊包中使用import語句的時候,不同的語法會導致不同的模塊搜索導入方式,常見的導入方式如下:
需要注意的是,這些導入方式都是對於模塊包而言,對於一般的模塊還是從sys.path搜索入手。
Python腳本運行的方式?
當使用python命令直接執行一個py文件的時候,該文件就是以top level script方式運行,此時文件的__name__屬性則為__main__。
# test.py
print __name__
# output
__main__
當文件使用包模塊的方式運行的時候,文件的__name__屬性則為模塊的路徑(從top level script的目錄開始),包模塊的例子目錄結構如下:
├── main.py
└── pac
├── __init__.py
└── moduleA.py
筆者將直接運行main.py文件,代碼如下:
## main.py
from pac import moduleA
## moduleA.py
print __name__
## output
pac.moduleA
這兩種運行方式還有不同的地方是,當使用top level script的方式運行的時候是不會生成字節碼的(即.pyc文件),而通過包模塊的方式則會生成字節碼。
假設如下的import語句:
import string
這個string是當前目錄下的string模塊呢,還是在標准庫的string模塊呢?在早期的Python中,當使用import語句的時候,都會優先尋找目錄內的模塊,因此這就是隱式相對導入。
但是在有同名模塊的情況下,如果還想引用標准庫中的string模塊那該怎麼辦?因此Python實現了絕對導入,在絕對導入的模式下,當使用import string的時候,就會優先搜索當前目錄以外的模塊。絕對導入模式是Python3默認采取的包導入方式,其實這種方式在Python2.5及以上版本就已經實現,要想使用只需加上:
from __future__ import absolute_import
關於隱式相對導入於絕對導入的例子如下:
包結構:
├── main.py
└── pac
├── __init__.py
├── __init__.pyc
├── explicit_import.py
├── explicit_import.pyc
├── implicit_import.py
├── implicit_import.pyc
├── string.py
└── string.pyc
代碼如下:
# main.py
from pac import implicit_import
from pac import explicit_import
# explicit_import.py
from __future__ import absolute_import
import string
print string.digits
# implicit_import.py
import string
print string.digits
# string.py
digits = '2333'
## output
2333(relative import)
0123456789(absolute import)
絕對導入還有一種使用方法,比如在explicit_import.py中可以通過:
from pac.implicit_import import *
來引用implicit_import文件中的變量。
雖然絕對導入能夠完成相對導入的所有功能,但是顯式的相對導入也是可以接受的。當使用.語法的時候就是使用相對導入:
# 導入當前目錄下的string模塊
# right
from . import string
# wrong
import .string
至於下面的導入方法錯誤的原因,這是因為Python語法不支持的緣故。
同時值得注意的是,顯式的相對導入是根據模塊的__name__屬性來確定相對位置的,因此如果是在top level script中,顯式相對導入並不能使用,會報出如下錯誤:
ValueError: Attempted relative import in non-package
當然,在PEP 366 – Main module explicit relative imports中,也給出了在Python中執行非包內的模塊(作為top level腳本執行)使用顯示相對導入的方法:在執行python命令時加上-m選項,此時就會啟用模塊的__package__屬性。
詳細的關於相對導入與絕對導入參考:PEP 328 – Imports: Multi-Line and Absolute/Relative。
Ubuntu 14.04安裝Python 3.3.5 http://www.linuxidc.com/Linux/2014-05/101481.htm
CentOS上源碼安裝Python3.4 http://www.linuxidc.com/Linux/2015-01/111870.htm
《Python核心編程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm
《Python開發技術詳解》.( 周偉,宗傑).[高清PDF掃描版+隨書視頻+代碼] http://www.linuxidc.com/Linux/2013-11/92693.htm
Python腳本獲取Linux系統信息 http://www.linuxidc.com/Linux/2013-08/88531.htm
在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm
Python 語言的發展簡史 http://www.linuxidc.com/Linux/2014-09/107206.htm