如非特別說明,下文皆基於Python3
摘要
為重複使用以及更好的維護程式碼,Python
#使用了模組與套件;一個Python
檔案就是一個模組,套件是組織模組的特殊目錄(包含__init__.py
檔)。
模組搜尋路徑,Python
解釋器在特定的目錄中搜尋模組,運行時sys.path
即搜尋路徑。
使用import
關鍵字匯入模組,注意 import *
與__all__
的關係。
A module is a file containing Python definitions and statements
Python
模組就是包含定義以及語句的文件,文件名是模組的名字加上.py
後綴。
假設有一個完成特定功能,很好用的函數或類別。為了使用這個功能,不得不把這段程式碼複製到需要使用的每一個檔案中。重複程式碼是程式設計的大忌,如果功能實現需要修改,會不得不修改每一個出現的地方,這是反人類的。
重用能夠很好的解決這個問題,實際上,函數,類別等結構在一定程度上也為重用提供了便利。
Python
中,將一系列相關的函數,類別等組織在一個檔案中,每一個檔案都是一個Python
模組。
使用import
關鍵字導入模組(模組需在搜尋路徑中):
import sys ;基礎導入語句。
import sys as system;為導入的名字取別名。
from sys import path;導入模組特定元素。
from sys import *;從sys匯入全部可導入名字
import-only-once
模組只導入一次這種行為在大多數情況下是一種實質性的優化,在同一個解釋器生命週期內,多次使用import
語句導入同一個模組,導入只發生一次。
這一點可以在模組中加入輸出語句證明。
import *
與__all__
#使用import *
可能會污染目前模組的名字空間,導入了一些不需要引用的名字。因此不建議使用。
事實上,規範的第三方模組會提供一個模組公共接口,暴露該模組可用的介面。公共介面由模組名為__all__
的清單定義。
如定義名為mtest1
的模組:
__all__ = ['test1', 'test12']def test1():print('test1')def test11():print('test11')def test12():print('test12')
使用全部導入的方式:
>>> form mtest1 import *>>> dir()>>> ['__annotations__', '__builtins__', '__doc__', '__loader__','__name__', '__package__', '__spec__', 'test1', 'test12']
可以看到函數test11()
並沒有被導入,這就是__all__
#的作用了。
為了更好組織模組,將模組分組為套件(package)。
從檔案系統來看,套件就是模組所在目錄。為使Python
解釋器將其區別普通目錄作為套件看待,套件中必須直接包含一個名為__init__.py
的檔案(模組)。
套件基本上就是另一類模組,不同的地方在於套件能包含其他模組與套件。套件作為一個模組,其實內容其實就是檔案__init__.py
(模組)的內容。
如名為constants
的套件,檔案constants/__init__.py
如下:
PI = 3.14
那麼可以將套件constants
當作普通模組對待:
import constantsprint(constants.PI)
如果要建置一個名為drawing
的套件,其中包含shapes
和colors
模組,需要建立目錄和檔案:
檔案/目錄 | 描述 |
---|---|
~/python | #加入到搜尋路徑中的目錄 |
套件目錄(drawing套件) | |
套件程式碼(drawing模組) | |
color模組 | |
#shapes模組 |