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

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