天天看點

Python 學習 第13篇:子產品搜尋路徑和包導入

在導入自定義的子產品時,除了指定子產品名之外,也需要指定目錄,由于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__清單中的變量。