pkgutil --- 套件擴充工具程式

原始碼:Lib/pkgutil.py


此模組提供了引入系統 (import system) 的工具程式,特別是套件相關支援。

class pkgutil.ModuleInfo(module_finder, name, ispkg)

一個包含模組資訊之簡短摘要的附名元組 (namedtuple)。

在 3.6 版被加入.

pkgutil.extend_path(path, name)

擴充組成一個套件之模組的搜尋路徑。預期用法是將以下程式碼放入套件的 __init__.py

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

For each directory on sys.path that has a subdirectory that matches the package name, add the subdirectory to the package's __path__. This is useful if one wants to distribute different parts of a single logical package as multiple directories.

它還會尋找 *.pkg 檔案,其中開頭的 *name 引數相符。此功能類似於 *.pth 檔案(更多資訊請參閱 site 模組),但他不特別處理以 import 為開頭的行。*.pkg 檔案從表面上看是受信任的:除了跳過空行和備註之外,在 *.pkg 檔案中找到的所有條目都將新增到路徑中,無論它們是否存在於檔案系統。(這是一個功能。)

如果輸入路徑不是串列(像是凍結套件 (frozen package) 的情況),它將原封不動地被回傳。輸入路徑不會被修改;而是回傳擴充後的副本。僅將項目附加到副本的尾端。

sys.path 被假設是一個序列,sys.path 中的項目裡,若不是代表現存目錄的字串則將被忽略。sys.path 上用作檔案名稱時導致錯誤的 Unicode 項目可能會導致此函式引發例外(與 os.path.isdir() 行為一致)。

pkgutil.find_loader(fullname)

取得給定之 fullname 的模組 loader

這是一個 importlib.util.find_spec() 的向後相容包裝器,它將大多數的失敗轉換為 ImportError 並且僅回傳載入器而不是完整的 importlib.machinery.ModuleSpec

在 3.3 版的變更: 更新為直接基於 importlib,而不是依賴套件內部 PEP 302 的引入模擬 (import emulation)。

在 3.4 版的變更: 基於 PEP 451 來更新

Deprecated since version 3.12, will be removed in version 3.14: 改用 importlib.util.find_spec()

pkgutil.get_importer(path_item)

取得給定之 path_itemfinder

如果回傳的尋檢器 (finder) 是由路徑勾點 (path hook) 所新建立的,則它會被快取在 sys.path_importer_cache 中。

如果需要重新掃描 sys.path_hooks,可以手動清除快取(或部分快取)。

在 3.3 版的變更: 更新為直接基於 importlib,而不是依賴套件內部 PEP 302 的引入模擬 (import emulation)。

pkgutil.get_loader(module_or_name)

取得 module_or_nameloader 物件。

如果可以透過正常引入機制存取模組或套件,則回傳該機制相關部分的包裝器。如果找不到或無法引入模組,則回傳 None。如果指定的模組尚未被引入,則引入其包含的套件(如有存在)以建立套件 __path__

在 3.3 版的變更: 更新為直接基於 importlib,而不是依賴套件內部 PEP 302 的引入模擬 (import emulation)。

在 3.4 版的變更: 基於 PEP 451 來更新

Deprecated since version 3.12, will be removed in version 3.14: 改用 importlib.util.find_spec()

pkgutil.iter_importers(fullname='')

yield 給定模組名稱的 finder 物件。

如果 fullname 包含 '.',則尋檢器將針對包含 fullname 的套件,否則它們全部會是在頂層被註冊的尋檢器(即 sys.meta_pathsys.path_hooks 上的尋檢器)。

如果指定的模組位於套件中,則作為呼叫此函式的副作用 (side effect) ,該套件會被引入。

如果未指定模組名稱,則會產生所有頂層尋檢器。

在 3.3 版的變更: 更新為直接基於 importlib,而不是依賴套件內部 PEP 302 的引入模擬 (import emulation)。

pkgutil.iter_modules(path=None, prefix='')

yield path 上所有子模組的 ModuleInfo,或者如果 pathNone,則產生 sys.path 上的所有頂層模組。

path 應該是 None 或用來尋找模組的路徑串列。

prefix 是在輸出的每個模組名稱前面的輸出字串。

備註

僅適用於有定義 iter_modules() 方法的 finder。此介面並非是標準的,因此該模組還提供了 importlib.machinery.FileFinderzipimport.zipimporter 的實作。

在 3.3 版的變更: 更新為直接基於 importlib,而不是依賴套件內部 PEP 302 的引入模擬 (import emulation)。

pkgutil.walk_packages(path=None, prefix='', onerror=None)

path 上的所有模組遞迴 yield 出 ModuleInfo,或如果 pathNone 則 yield 所有可存取的模組。

path 應該是 None 或用來尋找模組的路徑串列。

prefix 是在輸出的每個模組名稱前面的輸出字串。

請注意,此函式必須引入給定之 path 上的所有套件不是所有模組!),以便存取 __path__ 屬性來尋找子模組。

onerror 是一個函式,如果在嘗試引入套件時發生任何例外,則使用一個引數(正在引入之套件的名稱)來呼叫函式。如果未提供 onerror 函式,則會捕獲並忽略 ImportError,同時傳播所有其他例外並終止搜尋。

範例:

# list all modules python can access
walk_packages()

# list all submodules of ctypes
walk_packages(ctypes.__path__, ctypes.__name__ + '.')

備註

僅適用於有定義 iter_modules() 方法的 finder。此介面並非是標準的,因此該模組還提供了 importlib.machinery.FileFinderzipimport.zipimporter 的實作。

在 3.3 版的變更: 更新為直接基於 importlib,而不是依賴套件內部 PEP 302 的引入模擬 (import emulation)。

pkgutil.get_data(package, resource)

從套件中取得資源。

這是 loader get_data API 的包裝器。package 引數應該是採用標準模組格式 (foo.bar) 的套件名稱。resource 引數應為相對檔案名稱的形式,並使用 / 作為路徑分隔符號。不允許使用父目錄名稱 ..,也不允許使用根目錄名稱(以 / 開頭)。

該函式回傳一個二進位字串,它是指定資源的內容。

對於位於檔案系統中且已被引入過的套件,這大致相當於:

d = os.path.dirname(sys.modules[package].__file__)
data = open(os.path.join(d, resource), 'rb').read()

如果無法定位或載入套件,或者它使用不支援 get_dataloader 則回傳 None。特別是命名空間套件loader 不支援 get_data

pkgutil.resolve_name(name)

將名稱解析為物件。

標準函式庫中的許多地方都使用了此功能(請參閱 bpo-12915),且相同功能也被用於擁有廣大使用者的第三方套件,如 setuptools、Django 和 Pyramid。

name 預期要是以下格式之一的字串,其中 W 是有效 Python 識別字的簡寫,而點 (dot) 代表這些偽正規表示式 (pseudo-regex) 中的字面句點 (literal period):

  • W(.W)*

  • W(.W)*:(W(.W)*)?

第一種形式僅是為了要向後相容。它假設點名稱 (dotted name) 的某些部分是一個套件,其餘部分是該套件內某處的物件,其可能巢狀地存在於 (nested) 其他物件內。由於無法透過檢查 (inspection) 來推斷出套件停止的位置和物件層次結構的開始位置,因此必須使用此形式來重複嘗試引入。

在第二種形式中,呼叫者透過使用一個冒號來明確標明分隔點:冒號左側的點名稱是要引入的套件,右側的點名稱是該套件內的物件層次結構。這種形式只需要一次引入。如果它以冒號結尾,則回傳一個模組物件。

此函式會回傳一個物件(可能是一個模組),或引發以下其中一個例外:

ValueError -- 如果 name 不是可辨識的格式。

ImportError -- 如果在不應該失敗的情況下引入失敗。

AttributeError -- 如果在遍歷引入套件中的物件層次結構以取得所需物件時發生失敗。

在 3.9 版被加入.