在導入自定義的子產品時,除了指定子產品名之外,也需要指定目錄,由于Python把目錄稱作包,是以,這類導入被稱為包導入。包導入把計算機上的目錄變成Python的命名空間,而目錄中所包含的子目錄和子產品檔案則對應命名空間中的屬性。
Python已經導入的子產品儲存在一個内置的sys.modules字典中,以便記錄哪些子產品已經記錄了。
導入過程首先需要定位導入檔案的位置,也就是,告訴Python到何處去找到要導入的檔案,是以,需要設定子產品的搜尋路徑。在大多數情況下,Python會自動到預設的目錄下去搜尋子產品;如果要在預設的目錄之外導入子產品,就需要知道Pyhon搜尋子產品路徑的機制。
Python搜尋子產品的路徑是由四部分構成的:程式的主目錄、PATHONPATH目錄、标準連結庫目錄和.pth檔案的目錄,這四部分的路徑都存儲在sys.path 清單中。
1,程式的主目錄
主目錄是指包含程式的頂層腳本的目錄,Python首先會到主目錄中搜尋子產品。
因為主目錄總是第一個被搜尋,如果子產品完全處于主目錄中,所有的導入都會自動完成,而不需要單獨配置路徑。
2,PATHONPATH目錄
PATHONPATH目錄是指PATHONPATH環境變量中配置的目錄,是第二個被搜尋的目錄,Python會從左到右搜尋PATHONPATH環境變量中設定的所有目錄。
3,标準連結庫目錄
标準連結庫目錄是Python按照标準子產品的目錄,是在安裝Python時自動建立的目錄,通常不需要添加到PYTHONPATH目錄中。
4,路徑檔案(.pth檔案)
在子產品搜尋目錄中,建立路徑檔案,字尾名為.pth,該檔案每一行都是一個有效的目錄。Python會讀取路徑檔案中的内容,每行都作為一個有效的目錄,加載到子產品搜尋路徑清單中。簡而言之,當路徑檔案存放到搜尋路徑中時,其作用和PYT)HONPATH環境變量的作用相同。
如果運作在Windows和Python3.0中,如果Python安裝目錄的頂層是C:\Python30,那麼可以把自定義的路徑檔案 mypath.pth 放到該目錄中。
也可以放到标準庫所在位置的sitepackages子目錄中(C:\Python30\Lib\sitepackages),來擴充子產品的搜搜路徑。
上述四種子產品搜尋路徑,能夠配置的選項隻有PYTHONPATH環境變量和路徑檔案。例如,在Windows平台上,建立PYTHONPATH環境變量,設定變量的值,兩個目錄使用分号隔開:
也可以建立一個名為 C:\Python30\pydirs.pth的文本檔案,其内容如下所示:
如果想看子產品搜尋路徑在機器上的實際配置,可以通過列印内置的sys.path清單來檢視,這個清單是sys子產品的path屬性。
其實,sys.path是子產品搜尋的路徑,Pytho在程式啟動時進行配置,自動把頂級檔案的主目錄,PYTHONPATH環境變量中配置的目錄,.pth檔案中目錄以及标準連接配接庫目錄加載到sys.path清單中,Python每次導入一個新的子產品,都是從sys.path清單中查找搜尋目錄。
搜尋路徑是指Python搜尋子產品的路徑字首,在import 語句的路徑上添加這些路徑,以構成子產品的絕對路徑。通常把存儲子產品的根目錄稱作容器目錄,記作dir0,容器目錄dir0必須包含在搜搜路徑中。
例如,在dir0目錄下,存在dri1/dir2/mod.py子產品,那麼導入該子產品需要設定搜尋路徑為dir0,并使用import 和路徑導入該子產品:
在import語句中列舉目錄名,以點号分隔,"."路徑是對應于dir0内的目錄,通過這個目錄可以找到mod.py子產品。
如果選擇使用包導入,就必須多遵循一條限制:包導入語句的路徑中,每個目錄内都必須有__init__.py檔案,否則包導入失敗。
對于目錄結構 dir0/dri1/dir2/mod.py
必須遵守以下規則:
dir0是容器目錄,不需要__init__.py檔案,如果有,也會被忽略。
dir0必須列在子產品搜尋路徑清單中,也就是說,dir0必須是主目錄,或者列在PYTHONPATH環境變量中等。
dir1和dir2都必須包含一個__init__.py檔案
__init__.py檔案是當 import 第一次周遊一個包目錄時所運作的檔案,可以包含Python程式代碼,也可以完全是空的。通常情況下,__init__.py檔案扮演了包初始化的鈎子,替目錄産生子產品命名空間以及使用目錄導入時實作from*行為的角色。
1,包的初始化
Python在首先導入某個目錄時,會自動執行該目錄下的__init__.py檔案中的所有程式代碼。
2,子產品命名空間的初始化
在包導入模型中,腳本内的目錄路徑,在導入後會變成真實的對象路徑,即,為目錄建立的子產品對象提供了命名空間。
3,from *語句的行為
在__init__.py檔案内使用__all__清單,來定義目錄以from * 語句形式導入時,需要導出的屬性清單。如果沒有設定__all__,from *語句不會自動加載潛逃與該目錄内的子子產品,也就是說,隻加載該目錄下的__init__.py檔案中羅列在__all__清單中的變量。