inspect — 检查活动对象

源代码: Lib/inspect.py


inspect 模块提供了一些有用的函数,帮助获取有关活动对象(例如模块、类、方法、函数、回溯、帧对象和代码对象)的信息。例如,它可以帮助您检查类的内容、检索方法的源代码、提取和格式化函数的参数列表,或获取显示详细回溯所需的所有信息。

此模块提供四种主要类型的服务:类型检查、获取源代码、检查类和函数以及检查解释器堆栈。

类型和成员

getmembers() 函数检索对象(例如类或模块)的成员。名称以“is”开头的函数主要作为 getmembers() 的第二个参数的便捷选择。它们还可以帮助您确定何时可以找到以下特殊属性(有关模块属性,请参阅 与导入相关的模块属性

类型

属性

说明

__doc__

文档字符串

__name__

定义此类的名称

__qualname__

限定名称

__module__

定义此类的模块名称

__type_params__

包含泛型类 类型参数 的元组

方法

__doc__

文档字符串

__name__

定义此方法的名称

__qualname__

限定名称

__func__

包含方法实现的函数对象

__self__

此方法绑定的实例,或 None

__module__

定义此方法的模块名称

函数

__doc__

文档字符串

__name__

定义此函数的名称

__qualname__

限定名称

__code__

包含已编译函数 字节码 的代码对象

__defaults__

位置或关键字参数的任何默认值的元组

__kwdefaults__

仅关键字参数的任何默认值的映射

__globals__

定义此函数的全局命名空间

__builtins__

内置命名空间

__annotations__

参数名称到注释的映射;"return" 键保留用于返回注释。

__type_params__

包含泛型函数的 类型参数 的元组

__module__

定义此函数的模块名称

回溯

tb_frame

此级别的帧对象

tb_lasti

字节码中最后尝试的指令的索引

tb_lineno

Python 源代码中的当前行号

tb_next

下一个内部回溯对象(由此级别调用)

f_back

下一个外部帧对象(此帧的调用者)

f_builtins

此帧看到的内置命名空间

f_code

在此帧中执行的代码对象

f_globals

此帧看到的全局命名空间

f_lasti

字节码中最后尝试的指令的索引

f_lineno

Python 源代码中的当前行号

f_locals

此帧看到的局部命名空间

f_trace

此帧的跟踪函数,或 None

代码

co_argcount

参数数量(不包括仅关键字参数、* 或 ** 参数)

co_code

原始已编译字节码的字符串

co_cellvars

单元格变量名称的元组(由包含范围引用)

co_consts

字节码中使用的常量的元组

co_filename

创建此代码对象的源文件名

co_firstlineno

Python 源代码中第一行的行号

co_flags

CO_* 标志的位图,此处 了解更多信息

co_lnotab

行号到字节码索引的编码映射

co_freevars

自由变量名称的元组(通过函数的闭包引用)

co_posonlyargcount

仅位置参数的数量

co_kwonlyargcount

仅关键字参数的数量(不包括 ** 参数)

co_name

定义此代码对象的名称

co_qualname

定义此代码对象的完全限定名称

co_names

除参数和函数局部变量之外的名称元组

co_nlocals

局部变量的数量

co_stacksize

虚拟机堆栈空间要求

co_varnames

参数和局部变量名称元组

生成器

__name__

名称

__qualname__

限定名称

gi_frame

gi_running

生成器是否正在运行?

gi_code

代码

gi_yieldfrom

yield fromNone 迭代的对象

异步生成器

__name__

名称

__qualname__

限定名称

ag_await

正在等待的对象,或 None

ag_frame

ag_running

生成器是否正在运行?

ag_code

代码

协程

__name__

名称

__qualname__

限定名称

cr_await

正在等待的对象,或 None

cr_frame

cr_running

协程是否正在运行?

cr_code

代码

cr_origin

协程创建的位置,或 None。请参阅 sys.set_coroutine_origin_tracking_depth()

内置

__doc__

文档字符串

__name__

此函数或方法的原始名称

__qualname__

限定名称

__self__

方法绑定的实例,或 None

3.5 版中已更改: 为生成器添加 __qualname__gi_yieldfrom 属性。

生成器的 __name__ 属性现在从函数名称设置,而不是代码名称,现在可以对其进行修改。

3.7 版中已更改: 为协程添加 cr_origin 属性。

3.10 版中已更改: 为函数添加 __builtins__ 属性。

inspect.getmembers(object[, predicate])

以按名称排序的 (name, value) 对列表形式返回对象的所有成员。如果提供了可选的 predicate 参数(该参数将使用每个成员的 value 对象调用),则仅包含谓词返回真值的成员。

注意

getmembers() 仅在参数为类且这些属性已列在元类的自定义 __dir__() 中时,才会返回元类中定义的类属性。

inspect.getmembers_static(object[, predicate])

以按名称排序的 (name, value) 对列表形式返回对象的所有成员,而不会通过描述符协议、__getattr__ 或 __getattribute__ 触发动态查找。或者,仅返回满足给定谓词的成员。

注意

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 函数,则返回 True,其中包括由 lambda 表达式创建的函数。

inspect.isgeneratorfunction(object)

如果对象是 Python 生成器函数,则返回 True

在 3.8 版本中已更改: 如果包装函数是 Python 生成器函数,则现在用 functools.partial() 包装的函数将返回 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

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

inspect.isasyncgen(object)

如果对象是通过 异步生成器 函数创建的 异步生成器迭代器,则返回 True

在 3.6 版本中添加。

inspect.istraceback(object)

如果对象是回溯,则返回 True

inspect.isframe(object)

如果对象是帧,则返回 True

inspect.iscode(object)

如果对象是代码,则返回 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() 为 true,则返回 True

例如,int.__add__ 便是如此。通过此测试的对象有 __get__() 方法,但没有 __set__() 方法,但除此之外,属性集是不同的。__name__ 属性通常是明智的,而 __doc__ 通常也是如此。

通过描述符实现的方法,如果也通过其他测试之一,则从 ismethoddescriptor() 测试返回 False,仅仅是因为其他测试承诺更多——例如,当对象通过 ismethod() 时,您可以依赖于有 __func__ 属性(等等)。

inspect.isdatadescriptor(object)

如果对象是数据描述符,则返回 True

数据描述符有 __set____delete__ 方法。示例包括属性(在 Python 中定义)、getset 和成员。后两者在 C 中定义,并且有更具体的测试可用于这些类型,这在 Python 实现中是可靠的。通常,数据描述符还将有 __name____doc__ 属性(属性、getset 和成员都有这两个属性),但这并不能得到保证。

inspect.isgetsetdescriptor(object)

如果对象是 getset 描述符,则返回 True

CPython 实现细节:getset 是通过 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)

返回给定可调用对象一个 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() 自动取消字符串化注释。解析注释时,globalslocalseval_str 参数会传递到 get_annotations() 中;请参阅 get_annotations() 的文档,了解如何使用这些参数的说明。

如果无法提供签名,则引发 ValueError,如果该类型的对象不受支持,则引发 TypeError。此外,如果注释已字符串化,并且 eval_str 不是 false,则 get_annotations() 中取消字符串化注释的 eval() 调用可能会引发任何类型的异常。

函数签名中的斜杠 (/) 表示其之前的参数是仅限位置的。有关更多信息,请参阅 仅限位置的参数常见问题解答条目

在 3.5 版中更改: 添加了 follow_wrapped 参数。传递 False 以专门获取 可调用对象 的签名(callable.__wrapped__ 将不会用于解包装饰的可调用对象。)

在 3.10 版中更改: 添加了 globalslocalseval_str 参数。

注意

在某些 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() 来制作一个修改后的副本。

在 3.5 版本中更改:Signature 对象现在可被腌制和 哈希

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'"
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 版中更改: 添加了 globalslocalseval_str 参数。

inspect.Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty)

Parameter 对象是不可变的。您可以使用 Parameter.replace() 创建修改后的副本,而不是修改 Parameter 对象。

在版本 3.5 中更改:Parameter 对象现在可进行腌制和 哈希

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'"

在版本 3.4 中更改: 在 Python 3.3 中,如果 kind 设置为 POSITIONAL_ONLY,则允许 Parameter 对象将 name 设置为 None。不再允许这样做。

class inspect.BoundArguments

Signature.bind()Signature.bind_partial() 调用的结果。保存参数到函数的参数的映射。

arguments

参数名称到参数值的可变映射。仅包含显式绑定的参数。 arguments 中的更改将在 argskwargs 中反映出来。

应结合 Signature.parameters 一起用于任何参数处理目的。

注意

对于 Signature.bind()Signature.bind_partial() 依赖于默认值的那些参数会被跳过。但是,如果需要,请使用 BoundArguments.apply_defaults() 来添加它们。

3.9 版中已更改: arguments 现在为 dict 类型。以前,它为 collections.OrderedDict 类型。

args

位置参数值的元组。从 arguments 属性动态计算。

kwargs

关键字参数值的字典。从 arguments 属性动态计算。

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()签名对象 提供了可调用内省的推荐 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 是给定帧的局部变量字典。

注意

此函数在 Python 3.5 中无意中被标记为已弃用。

inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue])

根据 getargvalues() 返回的四个值格式化一个漂亮的参数规范。format* 参数是相应的可选格式化函数,用于将名称和值转换为字符串。

注意

此函数在 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 为真,则使用 eval() 将类型为 str 的值取消字符串化。这适用于字符串化注释(from __future__ import annotations)。

  • 如果 obj 没有注释字典,则返回一个空字典。(函数和方法始终具有注释字典;类、模块和其他类型的可调用对象可能没有。)

  • 忽略类中的继承注释。如果类没有自己的注释字典,则返回一个空字典。

  • 出于安全考虑,所有对对象成员和字典值的访问都使用 getattr()dict.get()

  • 始终、始终、始终返回一个新创建的字典。

eval_str 控制是否使用调用 eval() 的结果替换类型为 str 的值

  • 如果 eval_str 为真,则对类型为 str 的值调用 eval()。(请注意,get_annotations 不会捕获异常;如果 eval() 引发异常,它将展开堆栈,超出 get_annotations 调用。)

  • 如果 eval_str 为假(默认),则类型为 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 是访问任何对象的注释字典的最佳实践。有关注释最佳实践的更多信息,请参阅 注释最佳实践

在 3.10 版中添加。

解释器堆栈

以下某些函数返回 FrameInfo 对象。为了向后兼容,这些对象允许对 positions 之外的所有属性执行类似元组的操作。此行为被视为已弃用,未来可能会被移除。

class inspect.FrameInfo
frame

frame 对象,记录与之对应。

filename

与记录对应的 frame 执行的代码关联的文件名。

lineno

记录对应的 frame 执行的代码关联的当前行的行号。

function

记录对应的 frame 正在执行的函数名。

code_context

记录对应的 frame 正在执行的源代码的上下文行列表。

index

正在 code_context 列表中执行的当前行索引。

positions

dis.Positions 对象,其中包含记录对应的 frame 正在执行的指令关联的起始行号、结束行号、起始列偏移量和结束列偏移量。

3.5 版中已更改:返回 命名元组,而不是 tuple

3.11 版中已更改:FrameInfo 现在是类实例(与之前的 命名元组 向后兼容)。

class inspect.Traceback
文件名

与该回溯对应的帧所执行的代码关联的文件名。

行号

与该回溯对应的帧所执行的代码关联的当前行的行号。

函数

与该回溯对应的帧所执行的函数名。

代码上下文

与该回溯对应的帧所执行的源代码的上下文行列表。

索引

code_context 列表中正在执行的当前行的索引。

位置

dis.Positions 对象,其中包含与该回溯对应的帧所执行的指令关联的起始行号、结束行号、起始列偏移量和结束列偏移量。

3.11 版中已更改:Traceback 现在是类实例(与之前的 命名元组 向后兼容)。

注意

保留对帧对象的引用(如在这些函数返回的第一帧记录中找到的)会导致程序创建引用循环。一旦创建了引用循环,则即使启用了 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)

获取异步生成器对象的当前状态。此函数旨在与 async def 函数创建的异步迭代器对象一起使用,这些函数使用 yield 语句,但会接受任何具有 ag_runningag_frame 属性的类似异步生成器对象。

可能的状态有

  • AGEN_CREATED:等待开始执行。

  • AGEN_RUNNING:当前由解释器执行。

  • AGEN_SUSPENDED:当前在 yield 表达式处挂起。

  • AGEN_CLOSED:执行已完成。

在 3.12 版本中添加。

还可以查询生成器的当前内部状态。这主要用于测试目的,以确保内部状态按预期更新

inspect.getgeneratorlocals(generator)

获取 generator 中活动局部变量到其当前值的映射。返回一个字典,其中映射从变量名到值。这等效于在生成器的主体中调用 locals(),并且所有相同的警告都适用。

如果生成器是没有任何关联帧的生成器,则返回一个空字典。如果生成器不是 Python 生成器对象,则引发TypeError

CPython 实现细节:此函数依赖于生成器公开 Python 堆栈帧以进行内省,这并不保证在所有 Python 实现中都是如此。在这种情况下,此函数将始终返回一个空字典。

在 3.3 版中添加。

inspect.getcoroutinelocals(coroutine)

此函数类似于getgeneratorlocals(),但适用于由async def函数创建的协程对象。

在 3.5 版本中添加。

inspect.getasyncgenlocals(agen)

此函数类似于getgeneratorlocals(),但适用于由async def函数创建的异步生成器对象,该函数使用yield语句。

在 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 版本中添加。

注意

这些标志特定于 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

打印指定对象的详细信息,而不是源代码