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__

定义此函数的模块名称

traceback

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_generator

返回拥有此帧的生成器或协程对象,如果帧是常规函数则返回 None

f_trace

此帧的跟踪函数,或 None

f_trace_lines

指示是否为每个源代码行触发跟踪事件

f_trace_opcodes

指示是否请求每操作码事件

clear()

用于清除对局部变量的所有引用

code

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

参数和局部变量名称的元组

co_lines()

返回一个迭代器,它生成连续的字节码范围

co_positions()

返回一个迭代器,其中包含每个字节码指令的源代码位置

replace()

返回带有新值的代码对象的副本

生成器

__name__

名称

__qualname__

限定名称

gi_frame

gi_running

生成器是否正在运行?

gi_suspended

生成器是否已暂停?

gi_code

code

gi_yieldfrom

yield from 迭代的对象,或 None

异步生成器

__name__

名称

__qualname__

限定名称

ag_await

正在等待的对象,或 None

ag_frame

ag_running

生成器是否正在运行?

ag_code

code

协程

__name__

名称

__qualname__

限定名称

cr_await

正在等待的对象,或 None

cr_frame

cr_running

协程是否正在运行?

cr_code

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__ 属性。

3.14 新版功能: 为帧添加 f_generator 属性。

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* 命名的模块的名称,不包括 enclosing package 的名称。文件扩展名与 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.ispackage(object)

如果对象是,则返回 True

在 3.14 版本加入。

inspect.isfunction(object)

如果对象是 Python 函数,其中包括通过 lambda 表达式创建的函数,则返回 True

inspect.isgeneratorfunction(object)

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

3.8 新版功能: 如果包装函数是 Python 生成器函数,则包装在 functools.partial() 中的函数现在返回 True

3.13 新版功能: 如果包装函数是 Python 生成器函数,则包装在 functools.partialmethod() 中的函数现在返回 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)

如果对象是回溯,则返回 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__() 方法或 __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, annotation_format=Format.VALUE)

返回给定 *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() 将尝试使用 annotationlib.get_annotations() 自动解除字符串化注解。*globals*、*locals* 和 *eval_str* 参数在解析注解时传递给 annotationlib.get_annotations();有关如何使用这些参数的说明,请参阅 annotationlib.get_annotations() 的文档。可以将 annotationlib.Format 枚举的成员传递给 *annotation_format* 参数,以控制返回注解的格式。例如,使用 annotation_format=annotationlib.Format.STRING 以字符串格式返回注解。

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

函数签名中的斜杠 (/) 表示其之前的参数是仅位置参数。更多信息请参阅关于仅位置参数的 FAQ 条目

3.5 新版功能: 添加了 *follow_wrapped* 参数。传入 False 以专门获取 *callable* 的签名(callable.__wrapped__ 将不会用于解包装饰过的可调用对象。)

3.10 新版功能: 添加了 *globals*、*locals* 和 *eval_str* 参数。

3.14 新版功能: 添加了 *annotation_format* 参数。

备注

某些可调用对象在 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, quote_annotation_strings=True)

创建 Signature 对象的字符串表示。

如果传入 *max_width*,该方法将尝试将签名适应于最多 *max_width* 字符的行。如果签名长于 *max_width*,所有参数将单独占一行。

如果 *quote_annotation_strings* 为 False,签名中的注解如果为字符串,则不带引号显示。这在签名使用 STRING 格式创建或使用了 from __future__ import annotations 时很有用。

在 3.13 版本加入。

3.14 新版功能: 添加了 *unquote_annotations* 参数。

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])

基于调用 replace 的实例创建一个新的 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 对象允许将 name 设置为 None,如果它们的 kind 设置为 POSITIONAL_ONLY。现在不再允许。

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 属性动态计算。可以按位置传递的参数包含在 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 参数为真,则返回的结构中给定列表中的每个类只出现一个条目。否则,使用多重继承的类及其子类将多次出现。

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 Object 提供了可调用自省的推荐 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, format=annotationlib.Format.VALUE)

计算对象的注释字典。

这是 annotationlib.get_annotations() 的别名;有关更多信息,请参阅该函数的文档。

注意

此函数可能会执行注释中包含的任意代码。有关更多信息,请参阅 自省注释的安全隐患

在 3.10 版本加入。

3.14 版本中已更改: 此函数现在是 annotationlib.get_annotations() 的别名。将其作为 inspect.get_annotations 调用将继续有效。

解释器堆栈

以下某些函数返回 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 现在是一个类实例(与之前的 命名元组 兼容)。

备注

保留对帧对象的引用(如这些函数返回的帧记录的第一个元素中所示)可能导致您的程序创建引用循环。一旦创建了引用循环,即使启用了 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.CO_HAS_DOCSTRING

当源代码中存在代码对象的文档字符串时,此标志会被设置。如果设置,它将是 co_consts 中的第一个元素。

在 3.14 版本加入。

inspect.CO_METHOD

当代码对象是在类作用域中定义的函数时,此标志会被设置。

在 3.14 版本加入。

备注

这些标志是 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

打印有关指定对象的信息而不是源代码