Python3學習筆記 | 二十二、Python的模組-模組的宏偉藍圖
- 2019 年 10 月 6 日
- 筆記
部分設備閱讀本文會存在程式碼錯亂的情況,可點擊閱讀原文鏈接到部落格中進行查看
一、模組簡介
模組是最高級別的程式組織單元,它將程式程式碼和數據封裝起來以便重用。從實際角度來看,模組往往對應於Python程式文件(或是用外部語言如C、Java或C#編寫而成的擴展)。每一個文件都是一個模組,並且模組導入其他模組之後就可以使用導入模組定義的變數名。模組由兩個語句和一個重要的內置函數進行處理。 import:使客戶端(導入者)以一個整體獲取一個模組 from:允許客戶端從一個模組文件中獲取特定的變數名 imp.reload:在不終止Python程式的情況下,提供了一種重新載入模組文件程式碼的方法。
為什麼使用模組
程式碼重用: 模組可以在文件中永久保存程式碼。我們可以按照需要任意次數地重新載入和重新運行模組。模組還是定義變數名的空間,被認作是屬性,可以被多個外部的客戶端引用。 系統命名空間的劃分: 模組可以被認為是變數名的軟體包。模組將變數名封裝進了自包含的軟體包,這樣就避免變數名的衝突。要使用這些變數,不精確定位的話是看不到這些變數的。 實現共享服務和數據: 模組對實現跨系統共享的組件是很方便的,只需要一個拷貝即可。
二、Python程式架構
1、如何組織一個程式
一般來講,一個Python程式包括了多個含有Python語句的文本文件。程式是作為一個主體的、頂層的文件來構造的,配合0個或多個支援的文件,在Python中這些文件稱作模組。 在Python中頂層文件(或者稱之為腳本)包含了程式的主要的控制流程:這就是你需要運行來啟動應用的文件。模組文件就是工具的庫,這些工具是用來收集頂層文件使用的組件。頂層文件使用了在模組文件中定義的工具,而這些模組使用了其他模組所定義的工具。 模組文件通常在運行時不需要直接做任何事。然而,它們定義的工具會在其他文件中使用。在Python中,一個文件導入了一個模組來獲得這個模組定義的工具的訪問許可權,這些工具被認作是這個模組的屬性。 附:屬性可以認為是變數(函數名也算是變數)
2、導入和屬性
下圖中,main.py是頂層文件,part1.py和part2.py是模組。main.py是導入part1.py和part2.py,part1.py和part2.py是相互導入、而且還導入了標準庫模組。我們要運行的是main.py,而通常part1.py和part2.py不會直接運行。

3、標準庫模組
之前頁面看到的「標準庫模組」是Python自身提供的,不需要程式設計師編寫的。 Python自帶了很多實用的模組,稱為標準鏈接庫。這個集合體大約有200個模組,包含與平台不相關的常見程式設計任務:作業系統介面、對象永久保存、文字模式匹配、網路和Internet腳本、GUI建構等。 這些工具都不是Python語言的組成部分,但是,你可以在任何安裝了標準Python的情況下,導入適當的模組來使用。因為這些都是標準庫模組,可以理所當然地認為它們一定可以用,而且在執行Python的絕大多數平台上都可以運行。 這裡,包含之前所使用過的os、sys等。這些標準庫的使用方法,可以在官方網站www.python.org里查到。
三、import
1、如何工作
在Python里import與C語言等的#include有些不同。C語言是把別的程式碼導入進來,但在Python里,是運行一次模組的程式碼。Python里第一次導入指定文件時,會執行三個步驟: 1、找到模組文件 2、編譯成位碼(需要時) 3、執行模組的程式碼來創建其所定義的對象 當你導入過一次後,導入相同模組時,會跳過這三個步驟。Python把載入的模組存儲到一個名為sys.modules的表中(是一個字典),並在一次導入操作的開始檢查該表。如果模組不存在,將會執行三個步驟。
2、搜索
首先,Python必須查找到import語句所引用的模組文件。之前我們import part1的時候,沒有寫具體路徑,但是程式還是能找到正確路徑。事實上,我們寫import的時候,只能寫文件名,不能寫路徑的。Python使用了標準模組搜索路徑來找出import語句所對應的模組文件。之後會對此說明。
>>> import part1 >>> import /tmp/part2 File "<stdin>", line 1 import /tmp/part2 ^ SyntaxError: invalid syntax >>> import part2
3、編譯(可選)
在遍歷模組搜索路徑之後,找到符合import語句的源程式碼之後,如果必要的話,Python接下來會將其編譯成位元組碼。 當發現已有位元組碼,並更新時間比源碼新,不會生成新的位元組碼。但是源碼更新時間比位元組碼新,或者沒有位元組碼,就會生成新的位元組碼。當沒有源碼,只有位元組碼的時候,也可以導入。 這個編譯過程,只在導入時進行。頂層文件,沒有被任何程式碼導入過,是不會生成位元組碼的,其位元組碼只會存儲在記憶體當中。
R:tmp tav$ ls -l | grep part1 -rw-r--r-- 1 tav wheel 90 Apr 12 19:37 part1.py -rw-r--r-- 1 tav wheel 416 Apr 12 19:38 part1.pyc
4、運行
import的最後一步是執行模組的位元組碼。文件中所有語句會依次執行。此步驟中任何對變數名的賦值運算,都會產生所得到的模組文件的屬性。
$ more part3.py print('This is part3 import') >>> import part3 This is part3 import >>> reload(part3) This is part3 import <module 'part3' from 'part3.pyc'> >>> import part3 >>>
如上所示,需要重新載入(運行)模組的話,可以使用reload。要是直接再次import的話,不會做任何操作的。
四、模組搜索路徑
在導入模組的時候,最重要的部分是:定位要導入的文件。因為我們要告訴Python到何處去找到要導入的文件。在Python里,模組搜索的路徑如下: 1、程式的主目錄 2、PYTHONPATH目錄(如果進行了設置) 3、標準鏈接庫目錄 4、任何.pth文件的內容(如果存在的話) 這四個組件合起來就成了sys.path。第一個和第三個是自動定義的。第二個與第四個就可以用於拓展路徑,下面介紹4個目錄使用方式。
1、主目錄
程式的主目錄是第一個搜索導入文件的路徑。這一入口的含義與你如何運行程式碼相關。當你運行程式的時候,這個入口是包含程式的頂層腳本文件的目錄。當在交互模式工作時,這個入口就是你當前工作的目錄。 因為這個目錄總是先被搜索,如果程式完全位於單一目錄,所有導入都會自動工作,而不需要配置路徑。另一方面,由於這個目錄是先搜索的,其文件也將覆蓋路徑上的其他目錄中具有同樣名稱的模組。如果你需要在自己的程式中使用庫模組的話,小心不要以這種方式意外地隱藏庫模組。
2、PYTHONPATH目錄
Python會對此環境變數(如果你設置了的話)從左至右搜索導入的模組,PYTHONPATH是設置包含Python程式文件的目錄的列表,這些目錄可以是用戶定義的,或平台特定的目錄名。你可以把想導入的目錄都加進來,而Python會使用你的設置來擴展模組搜索的路徑。 因為Python先會搜索主目錄,當跨目錄的時候,這個設置才顯得格外重要。也就是說,如果你需要被導入的文件與進行導入的文件處於不同目錄時可以使用此環境變數來設定。
3、標準庫目錄
Python會自動搜索標準庫模組安裝在機器上的那些目錄。因為這些一定會被搜索,通常是不需要添加到PYTHONPATH上的。
4、.pth文件目錄(Python3.x)
Python有一個相當新的功能,允許用戶把有效的目錄添加到模組搜索路徑中去,也就是文件名後綴為.pth的文件中。此文件可以放在: Windows中 - Python安裝目錄的頂層(例如C:Python3.x)或者在標準庫所在位置的sitepackages子目錄中(例如C:Python3.xLibsitepackages) 類Unix中 - 文件可能位於/usr/local/lib/python3.x/sitepackages或/usr/local/lib/sitepython中。 文件的格式是每一行一個目錄,Python會把重複的目錄和不存在的目錄過濾掉。
五、配置搜索路徑
我們可以手動設置的就是PYTHONPATH與.pth文件。PYTHONPATH設置方式,跟其他環境變數設置方式相同,每個路徑之間使用分號隔開(;),.pth設置方式就是之前所說的那些目錄里創建文件。 例如:在Windows,我們可以創建pydir.pth到C:Python3.x里。想要查看所有的搜索路徑,我們可以使用sys.path來查看
>>> import sys >>> sys.path ['', 'D:\Program Files\Anaconda\python37.zip', 'D:\Program Files\Anaconda\DLLs', 'D:\Program Files\Anaconda\lib', 'D:\Program Files\Anaconda', 'C:\Users\Administrator\AppData\Roaming\Python\Python37\site-packages', 'D:\Program Files\Anaconda\lib\site-packages', 'D:\Program Files\Anaconda\lib\site-packages\win32', 'D:\Program Files\Anaconda\lib\site-packages\win32\lib', 'D:\Program Files\Anaconda\lib\site-packages\Pythonwin']
六、模組文件選擇
我們導入模組的時候,不需要後綴名的。比如,導入mymodule.py時,只需要寫import mymodule 就可以。import b的時候,可以導入的文件為: 1、b.py源程式碼文件 2、b.pyc位元組碼文件 3、導入文件名為b的文件夾 4、編譯擴展模組(通常用C或C++來編寫),導入時使用動態鏈接(例如類Unix系統的b.so以及Cygwin和Windows的b.dll或b.pyd) 5、用C編寫好的內置模組,並通過靜態連接至Python 6、ZIP文件組件,導入時會自動解壓縮 7、記憶體內映像,對於frozen可執行文件 8、Java類,在Jython版本Python中使用 9、.NET文件,在IronPython的Python版本中使用