inspect — 檢查活動物件

原始碼: Lib/inspect.py


inspect 模組提供了幾個有用的函式,以幫助獲取有關活動物件的資訊,例如模組、類、方法、函式、回溯、幀物件和程式碼物件。 例如,它可以幫助你檢查類的內容、檢索方法的原始碼、提取和格式化函式的引數列表,或者獲取顯示詳細回溯所需的所有資訊。

此模組主要提供四種服務:型別檢查、獲取原始碼、檢查類和函式以及檢查直譯器堆疊。

型別和成員

getmembers() 函式檢索物件的成員,例如類或模組。 名稱以 “is” 開頭的函式主要作為 getmembers() 的第二個引數的便捷選擇。 它們還幫助你確定何時可以找到以下特殊屬性(有關模組屬性,請參閱 模組物件的匯入相關屬性

型別

屬性

描述

__doc__

文件字串

__name__

定義此類的名稱

__qualname__

限定名稱

__module__

定義此類的模組的名稱

__type_params__

一個元組,其中包含泛型類的 型別引數

方法

__doc__

文件字串

__name__

定義此方法的名稱

__qualname__

限定名稱

__func__

包含方法實現的函式物件

__self__

此方法繫結到的例項,或 None

__module__

定義此方法的模組的名稱

function

__doc__

文件字串

__name__

函式

__qualname__

限定名稱

定義此函式的名稱

__code__

包含已編譯的函式 位元組碼 的程式碼物件

__defaults__

用於位置或關鍵字引數的任何預設值的元組

__kwdefaults__

用於僅關鍵字引數的任何預設值的對映

__globals__

定義此函式的全域性名稱空間

__builtins__

builtins 名稱空間

__annotations__

__type_params__

引數名稱到註解的對映; "return" 鍵保留用於返回註解。

__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

此幀的跟蹤函式,或 None

程式碼

co_argcount

引數的數量(不包括僅關鍵字引數、* 或 ** args)

co_code

原始編譯位元組碼的字串

co_cellvars

單元格變數名稱的元組(由包含的作用域引用)

co_consts

位元組碼中使用的常量元組

co_filename

建立此程式碼物件的檔名

co_firstlineno

Python 原始碼中第一行的行號

co_flags

CO_* 標誌的點陣圖,在此處閱讀更多 此處

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__

限定名稱

yield from 迭代的物件,或 None

非同步生成器

ag_await

frame

正在等待的物件,或 None

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__

建立協程的位置,或 None。 請參閱 sys.set_coroutine_origin_tracking_depth()

__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.isfunction(object)

如果物件是 Python 函式,包括由 lambda 表示式建立的函式,則返回 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.iscoroutine(object)

如果物件是由 async def 函式建立的 協程,則返回 True

3.5 版本中新增。

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.isasyncgen(object)

如果物件是由非同步生成器函式建立的非同步生成器迭代器,則返回 True

3.6 版本中新增。

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.getfile(object)

返回定義物件的(文字或二進位制)檔案的名稱。如果物件是內建模組、類或函式,這將失敗並引發 TypeError 異常。

inspect.getmodule(object)

嘗試猜測物件是在哪個模組中定義的。如果無法確定模組,則返回 None

inspect.getsourcefile(object)

返回定義物件的 Python 原始碼檔案的名稱,如果無法識別獲取原始碼的方法,則返回 None。如果物件是內建模組、類或函式,這將失敗並引發 TypeError 異常。

inspect.getsourcelines(object)

返回物件的原始碼行列表和起始行號。引數可以是模組、類、方法、函式、回溯、幀或程式碼物件。原始碼以與物件對應的行列表的形式返回,行號指示在原始原始檔中找到第一行程式碼的位置。如果無法檢索原始碼,則會引發 OSError 異常。如果物件是內建模組、類或函式,則會引發 TypeError 異常。

3.3 版本更改: 引發 OSError 而不是 IOError,後者現在是前者的別名。

inspect.getsource(object)

返回物件的原始碼文字。引數可以是模組、類、方法、函式、回溯、幀或程式碼物件。原始碼以單個字串的形式返回。如果無法檢索原始碼,則會引發 OSError 異常。如果物件是內建模組、類或函式,則會引發 TypeError 異常。

3.3 版本更改: 引發 OSError 而不是 IOError,後者現在是前者的別名。

inspect.cleandoc(doc)

清理與程式碼塊對齊的文件字串中的縮排。

從第一行中刪除所有前導空格。從第二行開始,刪除可以統一刪除的任何前導空格。隨後刪除開頭和結尾的空行。此外,所有制表符都會擴充套件為空格。

使用 Signature 物件自省可呼叫物件

在 3.3 版本中新增。

Signature 物件表示可呼叫物件的呼叫簽名及其返回註解。要檢索 Signature 物件,請使用 signature() 函式。

inspect.signature(callable, *, follow_wrapped=True, globals=None, locals=None, eval_str=False)

返回給定 callableSignature 物件。

>>> 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() 自動取消字串化註解。當解析註解時,globalslocalseval_str 引數會傳遞到 get_annotations() 中;有關如何使用這些引數的說明,請參閱 get_annotations() 的文件。

如果無法提供簽名,則引發 ValueError 異常;如果不支援該型別的物件,則引發 TypeError 異常。此外,如果註解是字串化的,並且 eval_str 不為 False,則呼叫 eval() 來取消 get_annotations() 中的註解可能會引發任何型別的異常。

函式簽名中的斜槓 (/) 表示其之前的引數是僅限位置的引數。有關更多資訊,請參閱 有關僅限位置引數的常見問題解答條目

3.5 版本更改: 添加了 follow_wrapped 引數。傳遞 False 以獲取 callable 的特定簽名(不會使用 callable.__wrapped__ 來解包裝飾的可呼叫物件。)

3.10 版本更改: 添加了 globalslocalseval_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)

返回給定可呼叫物件 objSignature (或其子類)物件。

此方法簡化了 Signature 的子類化。

class MySignature(Signature):
    pass
sig = MySignature.from_callable(sum)
assert isinstance(sig, MySignature)

否則,其行為與 signature() 的行為相同。

3.5 版本中新增。

3.10 版本更改: 添加了 globalslocalseval_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 中的更改將反映在 argskwargs 中。

應與 Signature.parameters 結合使用,以進行任何引數處理。

inspect.getmembers(object[, predicate])

跳過 Signature.bind()Signature.bind_partial() 依賴於預設值的引數。但是,如果需要,請使用 BoundArguments.apply_defaults() 新增它們。

在 3.9 版本中變更: arguments 現在是 dict 型別。以前,它是 collections.OrderedDict 型別。

args

位置引數值的元組。從 arguments 屬性動態計算得出。

kwargs

關鍵字引數值的字典。從 arguments 屬性動態計算得出。可以按位置傳遞的引數包含在 args 中。

signature

對父 Signature 物件的引用。

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 版本中新增。

可以使用 argskwargs 屬性來呼叫函式

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* 引數的名稱,如果不支援任意位置引數,則為 Nonevarkw** 引數的名稱,如果不支援任意關鍵字引數,則為 Nonedefaults 是一個 n 元組,包含與最後 n 個位置引數對應的預設引數值,如果沒有定義此類預設值,則為 Nonekwonlyargs 是宣告順序中僅限關鍵字的引數名稱列表。kwonlydefaults 是一個字典,將 kwonlyargs 中的引數名稱對映到未提供引數時使用的預設值。annotations 是一個將引數名稱對映到註解的字典。特殊的鍵 "return" 用於報告函式返回值註解(如果有)。

請注意,signature()Signature 物件 提供了可呼叫物件自省的推薦 API,並支援在擴充套件模組 API 中有時會遇到的其他行為(如僅限位置引數)。保留此函式主要是為了在需要保持與 Python 2 inspect 模組 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 是引數名稱的列表。varargskeywords*** 引數的名稱,或者為 Nonelocals 是給定幀的區域性變數字典。

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)

argskwds 繫結到 Python 函式或方法 func 的引數名稱,就像使用它們呼叫一樣。對於繫結方法,還將第一個引數(通常命名為 self)繫結到關聯的例項。返回一個字典,將引數名稱(包括 *** 引數的名稱,如果有)對映到它們在 argskwds 中的值。如果錯誤地呼叫 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 的值保持不變。

globalslocals 會傳遞給 eval();有關更多資訊,請參閱 eval() 的文件。如果 globalslocalsNone,此函式可能會根據 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
frame

此記錄對應的 幀物件

filename

與此記錄對應的幀所執行的程式碼關聯的檔名。

lineno

與此記錄對應的幀所執行的程式碼關聯的當前行號。

function

與此記錄對應的幀所執行的函式名稱。

code_context

來自此記錄對應的幀所執行的原始碼的上下文行列表。

index

code_context 列表中當前執行的行的索引。

positions

一個 dis.Positions 物件,其中包含與此記錄對應的幀所執行的指令關聯的起始行號、結束行號、起始列偏移量和結束列偏移量。

在 3.5 版本中更改: 返回一個 命名元組,而不是 tuple

在 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

inspect.stack(context=1)

返回呼叫者堆疊的 FrameInfo 物件列表。返回列表中的第一個條目表示呼叫者;最後一個條目表示堆疊上的最外層呼叫。

在 3.5 版本中變更: 返回一個 命名元組 FrameInfo(frame, filename, lineno, function, code_context, index) 的列表。

在 3.11 版本中變更: 返回一個 FrameInfo 物件的列表。

inspect.trace(context=1)

返回當前幀和當前正在處理的異常被引發的幀之間的堆疊的 FrameInfo 物件列表。列表中的第一個條目表示呼叫者;最後一個條目表示引發異常的位置。

在 3.5 版本中變更: 返回一個 命名元組 FrameInfo(frame, filename, lineno, function, code_context, index) 的列表。

在 3.11 版本中變更: 返回一個 FrameInfo 物件的列表。

靜態獲取屬性

在獲取或檢查屬性是否存在時,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_runningcr_frame 屬性的類協程物件。

可能的狀態有

  • CORO_CREATED:等待開始執行。

  • CORO_RUNNING:當前正在由直譯器執行。

  • CORO_SUSPENDED:當前在 `await` 表示式處掛起。

  • CORO_CLOSED:執行已完成。

3.5 版本中新增。

inspect.getasyncgenstate(agen)

獲取非同步生成器物件的當前狀態。此函式旨在與透過使用 yield 語句的 async def 函式建立的非同步迭代器物件一起使用,但會接受任何具有 ag_runningag_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_NEWLOCALS

如果設定,則在執行程式碼物件時,將為幀的 f_locals 建立一個新字典。

inspect.CO_VARARGS

程式碼物件具有可變的位置引數(類似於 *args)。

inspect.CO_VARKEYWORDS

程式碼物件具有可變的關鍵字引數(類似於 **kwargs)。

inspect.CO_NESTED

當代碼物件是巢狀函式時,會設定此標誌。

inspect.CO_GENERATOR

當代碼物件是生成器函式時,會設定此標誌,即執行程式碼物件時返回生成器物件。

inspect.CO_COROUTINE

當代碼物件是協程函式時,會設定此標誌。 執行程式碼物件時,它會返回一個協程物件。 有關更多詳細資訊,請參見 PEP 492

3.5 版本中新增。

inspect.CO_ITERABLE_COROUTINE

此標誌用於將生成器轉換為基於生成器的協程。 具有此標誌的生成器物件可以在 await 表示式中使用,並且可以 yield from 協程物件。 有關更多詳細資訊,請參見 PEP 492

3.5 版本中新增。

inspect.CO_ASYNC_GENERATOR

當代碼物件是非同步生成器函式時,會設定此標誌。 執行程式碼物件時,它會返回一個非同步生成器物件。 有關更多詳細資訊,請參見 PEP 525

3.6 版本中新增。

inspect.getmembers(object[, predicate])

這些標誌特定於 CPython,並且可能未在其他 Python 實現中定義。 此外,這些標誌是實現細節,並且可能會在未來的 Python 版本中刪除或棄用。 建議從 inspect 模組中使用公共 API 來滿足任何內省需求。

緩衝區標誌

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

列印有關指定物件的資訊,而不是原始碼