inspect
— 檢查活動物件¶
原始碼: Lib/inspect.py
inspect
模組提供了幾個有用的函式,以幫助獲取有關活動物件的資訊,例如模組、類、方法、函式、回溯、幀物件和程式碼物件。 例如,它可以幫助你檢查類的內容、檢索方法的原始碼、提取和格式化函式的引數列表,或者獲取顯示詳細回溯所需的所有資訊。
此模組主要提供四種服務:型別檢查、獲取原始碼、檢查類和函式以及檢查直譯器堆疊。
型別和成員¶
getmembers()
函式檢索物件的成員,例如類或模組。 名稱以 “is” 開頭的函式主要作為 getmembers()
的第二個引數的便捷選擇。 它們還幫助你確定何時可以找到以下特殊屬性(有關模組屬性,請參閱 模組物件的匯入相關屬性)
型別 |
屬性 |
描述 |
---|---|---|
類 |
__doc__ |
文件字串 |
__name__ |
定義此類的名稱 |
|
__qualname__ |
限定名稱 |
|
__module__ |
定義此類的模組的名稱 |
|
__type_params__ |
一個元組,其中包含泛型類的 型別引數 |
|
方法 |
__doc__ |
文件字串 |
__name__ |
定義此方法的名稱 |
|
__qualname__ |
限定名稱 |
|
__func__ |
包含方法實現的函式物件 |
|
__self__ |
此方法繫結到的例項,或 |
|
__module__ |
定義此方法的模組的名稱 |
|
function |
__doc__ |
文件字串 |
__name__ |
函式 |
|
__qualname__ |
限定名稱 |
|
定義此函式的名稱 |
__code__ |
|
包含已編譯的函式 位元組碼 的程式碼物件 |
__defaults__ |
|
用於位置或關鍵字引數的任何預設值的元組 |
__kwdefaults__ |
|
用於僅關鍵字引數的任何預設值的對映 |
__globals__ |
|
定義此函式的全域性名稱空間 |
__builtins__ |
|
builtins 名稱空間 |
__annotations__ |
|
__type_params__ |
引數名稱到註解的對映; |
|
__module__ |
一個元組,其中包含泛型函式的 型別引數 |
|
定義此函式的模組的名稱 |
回溯 |
tb_frame |
此級別的幀物件 |
tb_lasti |
|
位元組碼中最後嘗試的指令的索引 |
tb_lineno |
|
Python 原始碼中的當前行號 |
tb_next |
|
frame |
下一個內部回溯物件(由此級別呼叫) |
幀 |
f_back |
下一個外部幀物件(此幀的呼叫者) |
|
f_builtins |
此幀看到的 builtins 名稱空間 |
|
f_code |
在此幀中執行的程式碼物件 |
|
f_globals |
tb_lasti |
|
此幀看到的全域性名稱空間 |
tb_lineno |
|
f_lasti |
f_lineno |
|
f_locals |
此幀看到的本地名稱空間 |
|
f_trace |
此幀的跟蹤函式,或 |
程式碼 |
co_argcount |
引數的數量(不包括僅關鍵字引數、* 或 ** args) |
|
co_code |
原始編譯位元組碼的字串 |
|
co_cellvars |
單元格變數名稱的元組(由包含的作用域引用) |
|
co_consts |
位元組碼中使用的常量元組 |
|
co_filename |
建立此程式碼物件的檔名 |
|
co_firstlineno |
Python 原始碼中第一行的行號 |
|
co_flags |
|
|
co_lnotab |
行號到位元組碼索引的編碼對映 |
|
co_freevars |
自由變數名稱的元組(透過函式的閉包引用) |
|
co_posonlyargcount |
僅位置引數的數量 |
|
co_kwonlyargcount |
僅關鍵字引數的數量(不包括 ** arg) |
|
co_name |
定義此程式碼物件的名稱 |
|
co_qualname |
定義此程式碼物件的完全限定名稱 |
|
co_names |
除引數和函式區域性變數之外的名稱元組 |
|
co_nlocals |
區域性變數的數量 |
|
co_stacksize |
所需的虛擬機器堆疊空間 |
|
co_varnames |
__name__ |
name |
__qualname__ |
限定名稱 |
|
引數和區域性變數名稱的元組 |
frame |
|
生成器 |
gi_frame |
|
gi_running |
f_trace |
|
生成器是否正在執行? |
gi_code |
|
gi_yieldfrom |
__name__ |
name |
__qualname__ |
限定名稱 |
|
由 |
非同步生成器 |
|
ag_await |
frame |
|
正在等待的物件,或 |
gi_frame |
|
ag_frame |
f_trace |
|
ag_running |
__name__ |
name |
__qualname__ |
限定名稱 |
|
ag_code |
非同步生成器 |
|
協程 |
frame |
|
cr_await |
cr_frame |
|
cr_running |
f_trace |
|
協程是否正在執行? |
cr_code |
|
cr_origin |
__doc__ |
文件字串 |
__name__ |
建立協程的位置,或 |
|
__qualname__ |
限定名稱 |
|
__self__ |
內建 |
原始名稱 此函式或方法
方法繫結到的例項,或 None
在 3.5 版本中更改: 新增 __qualname__
和 gi_yieldfrom
屬性到生成器。
生成器的 __name__
屬性現在從函式名稱而不是程式碼名稱設定,並且現在可以修改。
-
在 3.7 版本中更改: 新增
cr_origin
屬性到協程。 在 3.10 版本中更改: 為函式新增
__builtins__
屬性。inspect.getmembers(object[, predicate])¶
getmembers()
僅當引數為類,且這些屬性已在元類的自定義__dir__()
中列出時,才會返回元類中定義的類屬性。
- inspect.getmembers_static(object[, predicate])¶
返回一個物件的所有成員,以
(name, value)
對的列表形式返回,並按名稱排序,不會透過描述符協議、__getattr__ 或 __getattribute__ 觸發動態查詢。可以選擇僅返回滿足給定謂詞的成員。inspect.getmembers(object[, predicate])¶
getmembers_static()
可能無法檢索到 `getmembers` 可以獲取的所有成員(如動態建立的屬性),並且可能會找到 `getmembers` 無法找到的成員(如引發 AttributeError 的描述符)。在某些情況下,它還可能返回描述符物件而不是例項成員。3.11 版本中新增。
- inspect.getmodulename(path)¶
返回由檔案 *path* 命名的模組的名稱,不包括封閉包的名稱。副檔名會與
importlib.machinery.all_suffixes()
中的所有條目進行檢查。如果匹配,則返回刪除副檔名的最後一個路徑元件。否則,返回None
。請注意,此函式*僅*返回實際 Python 模組的有意義的名稱 - 可能引用 Python 包的路徑仍將返回
None
。在 3.3 版本中更改: 該函式直接基於
importlib
。
- inspect.ismodule(object)¶
如果物件是模組,則返回
True
。
- inspect.isclass(object)¶
如果物件是一個類(內建類或在 Python 程式碼中建立的類),則返回
True
。
- inspect.ismethod(object)¶
如果物件是在 Python 中編寫的繫結方法,則返回
True
。
- inspect.isgeneratorfunction(object)¶
如果物件是 Python 生成器函式,則返回
True
。在 3.8 版本中更改: 用
functools.partial()
包裝的函式,如果被包裝的函式是 Python 生成器函式,則現在返回True
。在 3.13 版本中更改: 用
functools.partialmethod()
包裝的函式,如果被包裝的函式是 Python 生成器函式,則現在返回True
。
- inspect.isgenerator(object)¶
如果物件是生成器,則返回
True
。
- inspect.iscoroutinefunction(object)¶
如果物件是 協程函式 (使用
async def
語法定義的函式)、包裝 協程函式 的functools.partial()
或用markcoroutinefunction()
標記的同步函式,則返回True
。3.5 版本中新增。
在 3.8 版本中更改: 用
functools.partial()
包裝的函式,如果被包裝的函式是 協程函式,則現在返回True
。在 3.12 版本中更改: 用
markcoroutinefunction()
標記的同步函式,現在返回True
。在 3.13 版本中更改: 用
functools.partialmethod()
包裝的函式,如果被包裝的函式是 協程函式,則現在返回True
。
- inspect.markcoroutinefunction(func)¶
如果一個可呼叫物件不能被
iscoroutinefunction()
檢測為 協程函式,則可以使用此裝飾器將其標記為 協程函式。如果同步函式返回 協程,並且該函式被傳遞給需要
iscoroutinefunction()
的 API,則這可能很有用。在可能的情況下,最好使用
async def
函式。也可以接受呼叫該函式並使用iscoroutine()
測試返回值。3.12 版本中新增。
- inspect.isawaitable(object)¶
如果物件可以在
await
表示式中使用,則返回True
。也可以用來區分基於生成器的協程和普通生成器
import types def gen(): yield @types.coroutine def gen_coro(): yield assert not isawaitable(gen()) assert isawaitable(gen_coro())
3.5 版本中新增。
- inspect.isasyncgenfunction(object)¶
如果物件是非同步生成器函式,則返回
True
,例如>>> async def agen(): ... yield 1 ... >>> inspect.isasyncgenfunction(agen) True
3.6 版本中新增。
在 3.8 版本中更改: 用
functools.partial()
包裝的函式,如果被包裝的函式是非同步生成器函式,則現在返回True
。在 3.13 版本中更改: 用
functools.partialmethod()
包裝的函式,如果被包裝的函式是 協程函式,則現在返回True
。
- inspect.istraceback(object)¶
如果物件是回溯(traceback),則返回
True
。
- inspect.isframe(object)¶
如果物件是幀(frame),則返回
True
。
- inspect.iscode(object)¶
如果物件是程式碼(code),則返回
True
。
- inspect.isbuiltin(object)¶
如果物件是內建函式或繫結的內建方法,則返回
True
。
- inspect.ismethodwrapper(object)¶
如果物件的型別是
MethodWrapperType
,則返回True
。這些是
MethodWrapperType
的例項,例如__str__()
、__eq__()
和__repr__()
。3.11 版本中新增。
- inspect.isroutine(object)¶
如果物件是使用者定義或內建的函式或方法,則返回
True
。
- inspect.isabstract(object)¶
如果物件是抽象基類,則返回
True
。
- inspect.ismethoddescriptor(object)¶
如果物件是方法描述符,但
ismethod()
、isclass()
、isfunction()
或isbuiltin()
返回 False,則返回True
。例如,
int.__add__
就是這種情況。透過此測試的物件具有__get__()
方法,但沒有__set__()
方法或__delete__()
方法。除此之外,屬性集各不相同。__name__
屬性通常是有意義的,而__doc__
通常也是如此。透過描述符實現的方法如果也通過了其他測試之一,則從
ismethoddescriptor()
測試返回False
,這僅僅是因為其他測試承諾提供更多資訊 —— 例如,當物件透過ismethod()
時,您可以依賴於擁有__func__
屬性(等等)。在 3.13 版本中變更: 此函式不再錯誤地將具有
__get__()
和__delete__()
但沒有__set__()
的物件報告為方法描述符(此類物件是資料描述符,而不是方法描述符)。
- inspect.isdatadescriptor(object)¶
如果物件是資料描述符,則返回
True
。資料描述符具有
__set__
或__delete__
方法。示例包括屬性(在 Python 中定義)、getsets 和成員。後兩者在 C 中定義,並且有更具體的測試可用於這些型別,這在不同的 Python 實現中是穩健的。通常,資料描述符也將具有__name__
和__doc__
屬性(屬性、getsets 和成員都具有這兩個屬性),但這不能保證。
- inspect.isgetsetdescriptor(object)¶
如果物件是 getset 描述符,則返回
True
。CPython 實現細節: getsets 是透過
PyGetSetDef
結構在擴充套件模組中定義的屬性。對於沒有此類型別的 Python 實現,此方法將始終返回False
。
- inspect.ismemberdescriptor(object)¶
如果物件是成員描述符,則返回
True
。CPython 實現細節: 成員描述符是透過
PyMemberDef
結構在擴充套件模組中定義的屬性。對於沒有此類型別的 Python 實現,此方法將始終返回False
。
檢索原始碼¶
- inspect.getdoc(object)¶
獲取物件的文件字串,並使用
cleandoc()
進行清理。如果未提供物件的文件字串,且該物件是類、方法、屬性或描述符,則從繼承層次結構中檢索文件字串。如果文件字串無效或缺失,則返回None
。3.5 版本更改: 如果文件字串未被重寫,則現在會繼承。
- inspect.getcomments(object)¶
以單個字串的形式返回物件原始碼(對於類、函式或方法)之前緊鄰的任何註釋行,或者 Python 原始檔頂部(如果物件是模組)的註釋行。如果物件的原始碼不可用,則返回
None
。如果物件是在 C 或互動式 shell 中定義的,則可能會發生這種情況。
- inspect.getmodule(object)¶
嘗試猜測物件是在哪個模組中定義的。如果無法確定模組,則返回
None
。
- inspect.getsourcefile(object)¶
返回定義物件的 Python 原始碼檔案的名稱,如果無法識別獲取原始碼的方法,則返回
None
。如果物件是內建模組、類或函式,這將失敗並引發TypeError
異常。
- inspect.getsourcelines(object)¶
返回物件的原始碼行列表和起始行號。引數可以是模組、類、方法、函式、回溯、幀或程式碼物件。原始碼以與物件對應的行列表的形式返回,行號指示在原始原始檔中找到第一行程式碼的位置。如果無法檢索原始碼,則會引發
OSError
異常。如果物件是內建模組、類或函式,則會引發TypeError
異常。
- inspect.getsource(object)¶
返回物件的原始碼文字。引數可以是模組、類、方法、函式、回溯、幀或程式碼物件。原始碼以單個字串的形式返回。如果無法檢索原始碼,則會引發
OSError
異常。如果物件是內建模組、類或函式,則會引發TypeError
異常。
- inspect.cleandoc(doc)¶
清理與程式碼塊對齊的文件字串中的縮排。
從第一行中刪除所有前導空格。從第二行開始,刪除可以統一刪除的任何前導空格。隨後刪除開頭和結尾的空行。此外,所有制表符都會擴充套件為空格。
使用 Signature 物件自省可呼叫物件¶
在 3.3 版本中新增。
Signature
物件表示可呼叫物件的呼叫簽名及其返回註解。要檢索 Signature
物件,請使用 signature()
函式。
- inspect.signature(callable, *, follow_wrapped=True, globals=None, locals=None, eval_str=False)¶
返回給定 callable 的
Signature
物件。>>> from inspect import signature >>> def foo(a, *, b:int, **kwargs): ... pass >>> sig = signature(foo) >>> str(sig) '(a, *, b: int, **kwargs)' >>> str(sig.parameters['b']) 'b: int' >>> sig.parameters['b'].annotation <class 'int'>
接受各種 Python 可呼叫物件,從普通函式和類到
functools.partial()
物件。對於使用字串化註解(
from __future__ import annotations
)在模組中定義的物件,signature()
將嘗試使用get_annotations()
自動取消字串化註解。當解析註解時,globals、locals 和 eval_str 引數會傳遞到get_annotations()
中;有關如何使用這些引數的說明,請參閱get_annotations()
的文件。如果無法提供簽名,則引發
ValueError
異常;如果不支援該型別的物件,則引發TypeError
異常。此外,如果註解是字串化的,並且 eval_str 不為 False,則呼叫eval()
來取消get_annotations()
中的註解可能會引發任何型別的異常。函式簽名中的斜槓 (/) 表示其之前的引數是僅限位置的引數。有關更多資訊,請參閱 有關僅限位置引數的常見問題解答條目。
3.5 版本更改: 添加了 follow_wrapped 引數。傳遞
False
以獲取 callable 的特定簽名(不會使用callable.__wrapped__
來解包裝飾的可呼叫物件。)3.10 版本更改: 添加了 globals、locals 和 eval_str 引數。
inspect.getmembers(object[, predicate])¶
某些可呼叫物件在 Python 的某些實現中可能無法自省。例如,在 CPython 中,某些用 C 定義的內建函式不提供有關其引數的元資料。
CPython 實現細節: 如果傳遞的物件具有
__signature__
屬性,我們可能會使用它來建立簽名。確切的語義是實現細節,可能會在未通知的情況下更改。請查閱原始碼以瞭解當前的語義。
- class inspect.Signature(parameters=None, *, return_annotation=Signature.empty)¶
一個
Signature
物件表示一個函式的呼叫簽名及其返回註解。 對於函式接受的每個引數,它會在其parameters
集合中儲存一個Parameter
物件。可選的 parameters 引數是一個
Parameter
物件的序列,該序列會經過驗證,以檢查是否沒有重複名稱的引數,以及引數的順序是否正確,即首先是僅限位置的引數,然後是位置或關鍵字引數,並且具有預設值的引數在沒有預設值的引數之後。可選的 return_annotation 引數可以是任意 Python 物件。它表示可呼叫物件的“返回”註解。
Signature
物件是不可變的。請使用Signature.replace()
或copy.replace()
來建立修改後的副本。在 3.5 版本中更改:
Signature
物件現在是可 pickle 的和 可雜湊的。- empty¶
一個特殊的類級別標記,用於指定缺少返回註解。
- parameters¶
一個引數名稱到相應
Parameter
物件的有序對映。引數按照嚴格的定義順序出現,包括僅限關鍵字的引數。在 3.7 版本中更改: Python 僅在 3.7 版本之後才明確保證保留僅限關鍵字引數的宣告順序,儘管實際上此順序在 Python 3 中始終被保留。
- return_annotation¶
可呼叫物件的“返回”註解。如果可呼叫物件沒有“返回”註解,則此屬性設定為
Signature.empty
。
- bind(*args, **kwargs)¶
建立從位置引數和關鍵字引數到引數的對映。 如果
*args
和**kwargs
與簽名匹配,則返回BoundArguments
,否則引發TypeError
。
- bind_partial(*args, **kwargs)¶
工作方式與
Signature.bind()
相同,但允許省略一些必需的引數(模仿functools.partial()
的行為)。 返回BoundArguments
,或者如果傳遞的引數與簽名不匹配則引發TypeError
。
- replace(*[, parameters][, return_annotation])¶
基於呼叫
replace()
的例項建立一個新的Signature
例項。 可以傳遞不同的 parameters 和/或 return_annotation 以覆蓋基本簽名的相應屬性。 要從複製的Signature
中刪除return_annotation
,請傳入Signature.empty
。>>> def test(a, b): ... pass ... >>> sig = signature(test) >>> new_sig = sig.replace(return_annotation="new return anno") >>> str(new_sig) "(a, b) -> 'new return anno'"
Signature
物件也受泛型函式copy.replace()
支援。
- format(*, max_width=None)¶
建立
Signature
物件的字串表示形式。如果傳遞了 max_width,則該方法將嘗試將簽名放入最多 max_width 個字元的行中。 如果簽名長度超過 max_width,則所有引數將位於單獨的行上。
3.13 版本中新增。
- classmethod from_callable(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False)¶
返回給定可呼叫物件 obj 的
Signature
(或其子類)物件。此方法簡化了
Signature
的子類化。class MySignature(Signature): pass sig = MySignature.from_callable(sum) assert isinstance(sig, MySignature)
否則,其行為與
signature()
的行為相同。3.5 版本中新增。
3.10 版本更改: 添加了 globals、locals 和 eval_str 引數。
- class inspect.Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty)¶
Parameter
物件是不可變的。 您可以使用Parameter.replace()
或copy.replace()
來建立修改後的副本,而不是修改Parameter
物件。在 3.5 版本中更改: Parameter 物件現在是可 pickle 的和 可雜湊的。
- empty¶
一個特殊的類級別標記,用於指定缺少預設值和註解。
- name¶
引數的名稱,以字串形式表示。 該名稱必須是有效的 Python 識別符號。
CPython 實現細節: CPython 在用於實現推導式和生成器表示式的程式碼物件上生成形式為
.0
的隱式引數名稱。在 3.6 版本中更改: 這些引數名稱現在由該模組公開為諸如
implicit0
之類的名稱。
- default¶
引數的預設值。如果引數沒有預設值,則此屬性設定為
Parameter.empty
。
- annotation¶
引數的註解。如果引數沒有註解,則此屬性設定為
Parameter.empty
。
- kind¶
描述引數值如何繫結到引數。可以透過
Parameter
訪問可能的值(例如Parameter.KEYWORD_ONLY
),並支援比較和排序,順序如下名稱
含義
POSITIONAL_ONLY
值必須作為位置引數提供。僅位置引數是指在 Python 函式定義中出現在
/
條目(如果存在)之前的引數。POSITIONAL_OR_KEYWORD
值可以作為關鍵字引數或位置引數提供(這是 Python 實現的函式的標準繫結行為。)
VAR_POSITIONAL
未繫結到任何其他引數的位置引數的元組。這對應於 Python 函式定義中的
*args
引數。KEYWORD_ONLY
值必須作為關鍵字引數提供。僅關鍵字引數是指在 Python 函式定義中出現在
*
或*args
條目之後的引數。VAR_KEYWORD
未繫結到任何其他引數的關鍵字引數的字典。這對應於 Python 函式定義中的
**kwargs
引數。示例:列印所有沒有預設值的僅限關鍵字的引數
>>> def foo(a, b, *, c, d=10): ... pass >>> sig = signature(foo) >>> for param in sig.parameters.values(): ... if (param.kind == param.KEYWORD_ONLY and ... param.default is param.empty): ... print('Parameter:', param) Parameter: c
- kind.description¶
描述
Parameter.kind
的列舉值。3.8 版本新增。
示例:列印所有引數的描述
>>> def foo(a, b, *, c, d=10): ... pass >>> sig = signature(foo) >>> for param in sig.parameters.values(): ... print(param.kind.description) positional or keyword positional or keyword keyword-only keyword-only
- replace(*[, name][, kind][, default][, annotation])¶
基於呼叫它的例項建立一個新的
Parameter
例項。要覆蓋Parameter
屬性,請傳遞相應的引數。要從Parameter
中刪除預設值或/和註解,請傳遞Parameter.empty
。>>> from inspect import Parameter >>> param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42) >>> str(param) 'foo=42' >>> str(param.replace()) # Will create a shallow copy of 'param' 'foo=42' >>> str(param.replace(default=Parameter.empty, annotation='spam')) "foo: 'spam'"
Parameter
物件也受通用函式copy.replace()
支援。
在 3.4 版本中變更: 在 Python 3.3 中,如果
Parameter
物件的kind
設定為POSITIONAL_ONLY
,則允許將其name
設定為None
。現在不再允許這樣做。
- class inspect.BoundArguments¶
Signature.bind()
或Signature.bind_partial()
呼叫的結果。儲存了引數到函式引數的對映。- arguments¶
引數名稱到引數值的可變對映。僅包含顯式繫結的引數。
arguments
中的更改將反映在args
和kwargs
中。應與
Signature.parameters
結合使用,以進行任何引數處理。inspect.getmembers(object[, predicate])¶
跳過
Signature.bind()
或Signature.bind_partial()
依賴於預設值的引數。但是,如果需要,請使用BoundArguments.apply_defaults()
新增它們。在 3.9 版本中變更:
arguments
現在是dict
型別。以前,它是collections.OrderedDict
型別。
- apply_defaults()¶
為缺失的引數設定預設值。
對於可變位置引數(
*args
),預設值為空元組。對於可變關鍵字引數(
**kwargs
),預設值為空字典。>>> def foo(a, b='ham', *args): pass >>> ba = inspect.signature(foo).bind('spam') >>> ba.apply_defaults() >>> ba.arguments {'a': 'spam', 'b': 'ham', 'args': ()}
3.5 版本中新增。
def test(a, *, b): ... sig = signature(test) ba = sig.bind(10, b=20) test(*ba.args, **ba.kwargs)
參見
- PEP 362 - 函式簽名物件。
詳細規範、實現細節和示例。
類和函式¶
- inspect.getclasstree(classes, unique=False)¶
將給定的類列表排列成巢狀列表的層次結構。如果出現巢狀列表,則它包含派生自緊接在該列表之前的條目的類。每個條目是一個 2 元組,包含一個類及其基類元組。如果 unique 引數為 true,則返回的結構中為給定列表中的每個類只顯示一個條目。否則,使用多重繼承的類及其後代將多次出現。
- inspect.getfullargspec(func)¶
獲取 Python 函式的引數名稱和預設值。返回一個 命名元組
FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)
args 是位置引數名稱的列表。varargs 是
*
引數的名稱,如果不支援任意位置引數,則為None
。varkw 是**
引數的名稱,如果不支援任意關鍵字引數,則為None
。defaults 是一個 n 元組,包含與最後 n 個位置引數對應的預設引數值,如果沒有定義此類預設值,則為None
。kwonlyargs 是宣告順序中僅限關鍵字的引數名稱列表。kwonlydefaults 是一個字典,將 kwonlyargs 中的引數名稱對映到未提供引數時使用的預設值。annotations 是一個將引數名稱對映到註解的字典。特殊的鍵"return"
用於報告函式返回值註解(如果有)。請注意,
signature()
和 Signature 物件 提供了可呼叫物件自省的推薦 API,並支援在擴充套件模組 API 中有時會遇到的其他行為(如僅限位置引數)。保留此函式主要是為了在需要保持與 Python 2inspect
模組 API 相容的程式碼中使用。在 3.4 版本中更改: 此函式現在基於
signature()
,但仍然忽略__wrapped__
屬性,並在繫結方法的簽名輸出中包含已繫結的第一個引數。在 3.6 版本中更改: 此方法之前在 Python 3.5 中被記錄為已棄用,建議使用
signature()
,但該決定已被撤銷,以便為從遺留的getargspec()
API 遷移的單源 Python 2/3 程式碼恢復一個明確支援的標準介面。在 3.7 版本中更改: Python 僅在 3.7 版本之後才明確保證保留僅限關鍵字引數的宣告順序,儘管實際上此順序在 Python 3 中始終被保留。
- inspect.getargvalues(frame)¶
獲取有關傳遞到特定幀的引數的資訊。返回一個 命名元組
ArgInfo(args, varargs, keywords, locals)
。args 是引數名稱的列表。varargs 和 keywords 是*
和**
引數的名稱,或者為None
。locals 是給定幀的區域性變數字典。inspect.getmembers(object[, predicate])¶
此函式在 Python 3.5 中被意外標記為已棄用。
- inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue])¶
從
getargvalues()
返回的四個值格式化一個漂亮的引數規範。format* 引數是相應的可選格式化函式,這些函式被呼叫以將名稱和值轉換為字串。inspect.getmembers(object[, predicate])¶
此函式在 Python 3.5 中被意外標記為已棄用。
- inspect.getmro(cls)¶
返回一個元組,包含類 cls 的基類,包括 cls,按照方法解析順序排列。此元組中沒有類出現多次。請注意,方法解析順序取決於 cls 的型別。除非使用非常特殊的、使用者定義的元型別,否則 cls 將是元組的第一個元素。
- inspect.getcallargs(func, /, *args, **kwds)¶
將 args 和 kwds 繫結到 Python 函式或方法 func 的引數名稱,就像使用它們呼叫一樣。對於繫結方法,還將第一個引數(通常命名為
self
)繫結到關聯的例項。返回一個字典,將引數名稱(包括*
和**
引數的名稱,如果有)對映到它們在 args 和 kwds 中的值。如果錯誤地呼叫 func,即當func(*args, **kwds)
由於不相容的簽名而引發異常時,會引發相同型別且相同或相似訊息的異常。例如>>> from inspect import getcallargs >>> def f(a, b=1, *pos, **named): ... pass ... >>> getcallargs(f, 1, 2, 3) == {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)} True >>> getcallargs(f, a=2, x=4) == {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()} True >>> getcallargs(f) Traceback (most recent call last): ... TypeError: f() missing 1 required positional argument: 'a'
在 3.2 版本中新增。
自 3.5 版本起已棄用: 請改用
Signature.bind()
和Signature.bind_partial()
。
- inspect.getclosurevars(func)¶
獲取 Python 函式或方法 func 中對外部名稱的引用與其當前值的對映。返回一個 命名元組
ClosureVars(nonlocals, globals, builtins, unbound)
。nonlocals 將引用的名稱對映到詞法閉包變數,globals 對映到函式的模組全域性變數,builtins 對映到從函式體可見的內建函式。unbound 是函式中引用的一組名稱,這些名稱在當前模組全域性變數和內建函式中無法解析。如果 func 不是 Python 函式或方法,則會引發
TypeError
。在 3.3 版本中新增。
- inspect.unwrap(func, *, stop=None)¶
獲取 func 包裝的物件。它遵循
__wrapped__
屬性的鏈,返回鏈中的最後一個物件。stop 是一個可選的回撥函式,它接受包裝器鏈中的物件作為其唯一引數,如果回撥函式返回真值,則允許提前終止解包。如果回撥函式永遠不返回真值,則像往常一樣返回鏈中的最後一個物件。例如,
signature()
使用它來停止解包,如果鏈中的任何物件定義了__signature__
屬性。如果遇到迴圈,則會引發
ValueError
。在 3.4 版本中新增。
- inspect.get_annotations(obj, *, globals=None, locals=None, eval_str=False)¶
計算物件的註解字典。
obj
可以是可呼叫物件、類或模組。傳遞任何其他型別的物件會引發TypeError
。返回一個字典。
get_annotations()
每次呼叫都會返回一個新的字典;在同一物件上呼叫兩次將返回兩個不同但等效的字典。此函式為您處理以下幾個細節:
如果
eval_str
為 true,則型別為str
的值將使用eval()
進行去字串化。這旨在與字串化的註解一起使用(from __future__ import annotations
)。如果
obj
沒有註解字典,則返回一個空字典。(函式和方法始終具有註解字典;類、模組和其他型別的可呼叫物件可能沒有。)忽略類上的繼承註解。如果類沒有自己的註解字典,則返回一個空字典。
所有對物件成員和字典值的訪問都使用
getattr()
和dict.get()
來確保安全。始終、始終、始終返回一個新建立的字典。
eval_str
控制是否將str
型別的值替換為對這些值呼叫eval()
的結果。如果 eval_str 為 true,則會對型別為
str
的值呼叫eval()
。(請注意,get_annotations
不會捕獲異常;如果eval()
引發異常,它將展開堆疊,跳過get_annotations
呼叫。)如果 eval_str 為 false(預設值),則型別為
str
的值保持不變。
globals
和locals
會傳遞給eval()
;有關更多資訊,請參閱eval()
的文件。如果globals
或locals
為None
,此函式可能會根據type(obj)
將該值替換為上下文特定的預設值。如果
obj
是一個模組,則globals
預設為obj.__dict__
。如果
obj
是一個類,則globals
預設為sys.modules[obj.__module__].__dict__
,locals
預設為obj
類名稱空間。如果
obj
是一個可呼叫物件,則globals
預設為obj.__globals__
,但如果obj
是一個包裝過的函式(使用functools.update_wrapper()
),則會先將其解包。
呼叫
get_annotations
是訪問任何物件的 annotations 字典的最佳實踐。有關注釋最佳實踐的更多資訊,請參閱 註釋最佳實踐。3.10 版本中新增。
直譯器堆疊¶
以下一些函式返回 FrameInfo
物件。為了向後相容,這些物件允許對除 positions
之外的所有屬性執行類似元組的操作。此行為被視為已棄用,將來可能會被刪除。
- class inspect.FrameInfo¶
-
- filename¶
與此記錄對應的幀所執行的程式碼關聯的檔名。
- lineno¶
與此記錄對應的幀所執行的程式碼關聯的當前行號。
- function¶
與此記錄對應的幀所執行的函式名稱。
- code_context¶
來自此記錄對應的幀所執行的原始碼的上下文行列表。
- index¶
在
code_context
列表中當前執行的行的索引。
- positions¶
一個
dis.Positions
物件,其中包含與此記錄對應的幀所執行的指令關聯的起始行號、結束行號、起始列偏移量和結束列偏移量。
在 3.11 版本中更改:
FrameInfo
現在是一個類例項(與之前的 命名元組 向後相容)。
- class inspect.Traceback¶
- filename¶
與此回溯對應的幀所執行的程式碼關聯的檔名。
- lineno¶
與此回溯對應的幀所執行的程式碼關聯的當前行號。
- function¶
與此回溯對應的幀所執行的函式名稱。
- code_context¶
來自此回溯對應的幀所執行的原始碼的上下文行列表。
- index¶
在
code_context
列表中當前執行的行的索引。
- positions¶
一個
dis.Positions
物件,其中包含與此回溯對應的幀所執行的指令關聯的起始行號、結束行號、起始列偏移量和結束列偏移量。
在 3.11 版本中更改:
Traceback
現在是一個類例項(與之前的 命名元組 向後相容)。
inspect.getmembers(object[, predicate])¶
保留對幀物件的引用(如這些函式返回的幀記錄的第一個元素中所示)可能會導致您的程式建立引用迴圈。一旦建立了引用迴圈,即使啟用了 Python 的可選迴圈檢測器,也可以從形成迴圈的物件訪問的所有物件的生命週期都會變得更長。如果必須建立此類迴圈,請務必確保顯式斷開它們,以避免物件的延遲銷燬和記憶體消耗增加的情況發生。
儘管迴圈檢測器會捕獲這些迴圈,但可以透過在 finally
子句中刪除迴圈來確定幀(和區域性變數)的銷燬時間。如果 Python 編譯時停用了迴圈檢測器或使用 gc.disable()
,這也非常重要。例如
def handle_stackframe_without_leak():
frame = inspect.currentframe()
try:
# do something with the frame
finally:
del frame
如果您想保留幀(例如稍後列印回溯),您還可以使用 frame.clear()
方法來打破引用迴圈。
大多數這些函式支援的可選 context 引數指定要返回的上下文行數,這些行數圍繞當前行居中。
- inspect.getframeinfo(frame, context=1)¶
獲取有關幀或回溯物件的資訊。返回一個
Traceback
物件。在 3.11 版本中更改: 返回一個
Traceback
物件,而不是一個命名元組。
- inspect.getouterframes(frame, context=1)¶
獲取一個幀及其所有外部幀的
FrameInfo
物件列表。這些幀表示導致建立 frame 的呼叫。返回列表中的第一個條目表示 frame;最後一個條目表示 frame 堆疊上的最外層呼叫。在 3.5 版本中變更: 返回一個 命名元組
FrameInfo(frame, filename, lineno, function, code_context, index)
的列表。在 3.11 版本中變更: 返回一個
FrameInfo
物件的列表。
- inspect.getinnerframes(traceback, context=1)¶
獲取一個回溯的幀及其所有內部幀的
FrameInfo
物件列表。這些幀表示作為 frame 的結果進行的呼叫。列表中的第一個條目表示 traceback;最後一個條目表示引發異常的位置。在 3.5 版本中變更: 返回一個 命名元組
FrameInfo(frame, filename, lineno, function, code_context, index)
的列表。在 3.11 版本中變更: 返回一個
FrameInfo
物件的列表。
- inspect.currentframe()¶
返回呼叫者的堆疊幀的幀物件。
CPython 實現細節:此函式依賴於直譯器中的 Python 堆疊幀支援,這不能保證在 Python 的所有實現中都存在。如果在沒有 Python 堆疊幀支援的實現中執行,則此函式返回
None
。
靜態獲取屬性¶
在獲取或檢查屬性是否存在時,getattr()
和 hasattr()
都會觸發程式碼執行。像屬性這樣的描述符將被呼叫,並且可能會呼叫 __getattr__()
和 __getattribute__()
。
對於需要被動內省(如文件工具)的情況,這可能會很不方便。getattr_static()
具有與 getattr()
相同的簽名,但在獲取屬性時會避免執行程式碼。
- inspect.getattr_static(obj, attr, default=None)¶
檢索屬性,而不會透過描述符協議、
__getattr__()
或__getattribute__()
觸發動態查詢。注意:此函式可能無法檢索 `getattr` 可以獲取的所有屬性(如動態建立的屬性),並且可能會找到 `getattr` 無法找到的屬性(如引發 `AttributeError` 的描述符)。它還可能返回描述符物件,而不是例項成員。
如果例項的
__dict__
被另一個成員(例如屬性)所遮蔽,則此函式將無法找到例項成員。在 3.2 版本中新增。
getattr_static()
不會解析描述符,例如用 C 實現的物件上的槽描述符或 getset 描述符。將返回描述符物件,而不是底層屬性。
您可以使用以下程式碼處理這些問題。請注意,對於任意的 getset 描述符,呼叫這些描述符可能會觸發程式碼執行
# example code for resolving the builtin descriptor types
class _foo:
__slots__ = ['foo']
slot_descriptor = type(_foo.foo)
getset_descriptor = type(type(open(__file__)).name)
wrapper_descriptor = type(str.__dict__['__add__'])
descriptor_types = (slot_descriptor, getset_descriptor, wrapper_descriptor)
result = getattr_static(some_object, 'foo')
if type(result) in descriptor_types:
try:
result = result.__get__()
except AttributeError:
# descriptors can raise AttributeError to
# indicate there is no underlying value
# in which case the descriptor itself will
# have to do
pass
生成器、協程和非同步生成器的當前狀態¶
在實現協程排程器以及其他生成器高階用法時,確定生成器當前是否正在執行、是否正在等待開始或恢復執行,或者是否已終止會很有用。getgeneratorstate()
允許輕鬆確定生成器的當前狀態。
- inspect.getgeneratorstate(generator)¶
獲取生成器迭代器的當前狀態。
可能的狀態有
GEN_CREATED:等待開始執行。
GEN_RUNNING:當前正在由直譯器執行。
GEN_SUSPENDED:當前在 `yield` 表示式處掛起。
GEN_CLOSED:執行已完成。
在 3.2 版本中新增。
- inspect.getcoroutinestate(coroutine)¶
獲取協程物件的當前狀態。此函式旨在與透過
async def
函式建立的協程物件一起使用,但會接受任何具有cr_running
和cr_frame
屬性的類協程物件。可能的狀態有
CORO_CREATED:等待開始執行。
CORO_RUNNING:當前正在由直譯器執行。
CORO_SUSPENDED:當前在 `await` 表示式處掛起。
CORO_CLOSED:執行已完成。
3.5 版本中新增。
- inspect.getasyncgenstate(agen)¶
獲取非同步生成器物件的當前狀態。此函式旨在與透過使用
yield
語句的async def
函式建立的非同步迭代器物件一起使用,但會接受任何具有ag_running
和ag_frame
屬性的類非同步生成器物件。可能的狀態有
AGEN_CREATED:等待開始執行。
AGEN_RUNNING:當前正在由直譯器執行。
AGEN_SUSPENDED:當前在 `yield` 表示式處掛起。
AGEN_CLOSED:執行已完成。
3.12 版本中新增。
還可以查詢生成器的當前內部狀態。這主要用於測試目的,以確保內部狀態按預期更新
- inspect.getgeneratorlocals(generator)¶
獲取 generator 中即時區域性變數到其當前值的對映。返回一個字典,該字典將變數名對映到值。這等效於在生成器的正文中呼叫
locals()
,並應用所有相同的警告。如果generator是一個沒有當前關聯幀的生成器,則返回一個空字典。 如果generator不是Python生成器物件,則會引發
TypeError
。CPython 實現細節: 此函式依賴於生成器暴露用於內省的 Python 堆疊幀,這不能保證在 Python 的所有實現中都存在。 在這種情況下,此函式將始終返回一個空字典。
在 3.3 版本中新增。
- inspect.getcoroutinelocals(coroutine)¶
此函式類似於
getgeneratorlocals()
,但適用於由async def
函式建立的協程物件。3.5 版本中新增。
- inspect.getasyncgenlocals(agen)¶
此函式類似於
getgeneratorlocals()
,但適用於由使用yield
語句的async def
函式建立的非同步生成器物件。3.12 版本中新增。
程式碼物件位標誌¶
Python 程式碼物件具有 co_flags
屬性,它是以下標誌的點陣圖
- inspect.CO_OPTIMIZED¶
程式碼物件已使用快速區域性變數進行最佳化。
- inspect.CO_VARARGS¶
程式碼物件具有可變的位置引數(類似於
*args
)。
- inspect.CO_VARKEYWORDS¶
程式碼物件具有可變的關鍵字引數(類似於
**kwargs
)。
- inspect.CO_NESTED¶
當代碼物件是巢狀函式時,會設定此標誌。
- inspect.CO_GENERATOR¶
當代碼物件是生成器函式時,會設定此標誌,即執行程式碼物件時返回生成器物件。
緩衝區標誌¶
- class inspect.BufferFlags¶
這是一個
enum.IntFlag
,表示可以傳遞給實現 緩衝區協議 的物件的__buffer__()
方法的標誌。這些標誌的含義在 緩衝區請求型別 中進行了解釋。
- SIMPLE¶
- WRITABLE¶
- FORMAT¶
- ND¶
- STRIDES¶
- C_CONTIGUOUS¶
- F_CONTIGUOUS¶
- ANY_CONTIGUOUS¶
- INDIRECT¶
- CONTIG¶
- CONTIG_RO¶
- STRIDED¶
- STRIDED_RO¶
- RECORDS¶
- RECORDS_RO¶
- FULL¶
- FULL_RO¶
- READ¶
- WRITE¶
3.12 版本中新增。
命令列介面¶
inspect
模組還提供了從命令列進行基本內省的功能。
預設情況下,接受模組的名稱並列印該模組的原始碼。 可以透過附加冒號和目標物件的限定名稱來列印模組內的類或函式。
- --details¶
列印有關指定物件的資訊,而不是原始碼