inspect
— 检查活动对象¶
源代码: Lib/inspect.py
inspect
模块提供了几个有用的函数,以帮助获取有关活动对象的信息,例如模块、类、方法、函数、回溯、帧对象和代码对象。 例如,它可以帮助你检查类的内容、检索方法的源代码、提取和格式化函数的参数列表,或者获取显示详细回溯所需的所有信息。
此模块主要提供四种服务:类型检查、获取源代码、检查类和函数以及检查解释器堆栈。
类型和成员¶
getmembers()
函数检索对象的成员,例如类或模块。 名称以 “is” 开头的函数主要作为 getmembers()
的第二个参数的便捷选择。 它们还帮助你确定何时可以找到以下特殊属性(有关模块属性,请参阅 模块对象的导入相关属性)
类型 |
属性 |
描述 |
---|---|---|
类 |
__doc__ |
文档字符串 |
__name__ |
定义此类的名称 |
|
__qualname__ |
限定名称 |
|
__module__ |
定义此类的模块的名称 |
|
__type_params__ |
一个元组,其中包含泛型类的 类型参数 |
|
方法 |
__doc__ |
文档字符串 |
__name__ |
定义此方法的名称 |
|
__qualname__ |
限定名称 |
|
__func__ |
包含方法实现的函数对象 |
|
__self__ |
此方法绑定到的实例,或 |
|
__module__ |
定义此方法的模块的名称 |
|
function |
__doc__ |
文档字符串 |
__name__ |
函数 |
|
__qualname__ |
限定名称 |
|
定义此函数的名称 |
__code__ |
|
包含已编译的函数 字节码 的代码对象 |
__defaults__ |
|
用于位置或关键字参数的任何默认值的元组 |
__kwdefaults__ |
|
用于仅关键字参数的任何默认值的映射 |
__globals__ |
|
定义此函数的全局命名空间 |
__builtins__ |
|
builtins 命名空间 |
__annotations__ |
|
__type_params__ |
参数名称到注解的映射; |
|
__module__ |
一个元组,其中包含泛型函数的 类型参数 |
|
定义此函数的模块的名称 |
回溯 |
tb_frame |
此级别的帧对象 |
tb_lasti |
|
字节码中最后尝试的指令的索引 |
tb_lineno |
|
Python 源代码中的当前行号 |
tb_next |
|
frame |
下一个内部回溯对象(由此级别调用) |
帧 |
f_back |
下一个外部帧对象(此帧的调用者) |
|
f_builtins |
此帧看到的 builtins 命名空间 |
|
f_code |
在此帧中执行的代码对象 |
|
f_globals |
tb_lasti |
|
此帧看到的全局命名空间 |
tb_lineno |
|
f_lasti |
f_lineno |
|
f_locals |
此帧看到的本地命名空间 |
|
f_trace |
此帧的跟踪函数,或 |
代码 |
co_argcount |
参数的数量(不包括仅关键字参数、* 或 ** args) |
|
co_code |
原始编译字节码的字符串 |
|
co_cellvars |
单元格变量名称的元组(由包含的作用域引用) |
|
co_consts |
字节码中使用的常量元组 |
|
co_filename |
创建此代码对象的文件名 |
|
co_firstlineno |
Python 源代码中第一行的行号 |
|
co_flags |
|
|
co_lnotab |
行号到字节码索引的编码映射 |
|
co_freevars |
自由变量名称的元组(通过函数的闭包引用) |
|
co_posonlyargcount |
仅位置参数的数量 |
|
co_kwonlyargcount |
仅关键字参数的数量(不包括 ** arg) |
|
co_name |
定义此代码对象的名称 |
|
co_qualname |
定义此代码对象的完全限定名称 |
|
co_names |
除参数和函数局部变量之外的名称元组 |
|
co_nlocals |
局部变量的数量 |
|
co_stacksize |
所需的虚拟机堆栈空间 |
|
co_varnames |
__name__ |
name |
__qualname__ |
限定名称 |
|
参数和局部变量名称的元组 |
frame |
|
生成器 |
gi_frame |
|
gi_running |
f_trace |
|
生成器是否正在运行? |
gi_code |
|
gi_yieldfrom |
__name__ |
name |
__qualname__ |
限定名称 |
|
由 |
异步生成器 |
|
ag_await |
frame |
|
正在等待的对象,或 |
gi_frame |
|
ag_frame |
f_trace |
|
ag_running |
__name__ |
name |
__qualname__ |
限定名称 |
|
ag_code |
异步生成器 |
|
协程 |
frame |
|
cr_await |
cr_frame |
|
cr_running |
f_trace |
|
协程是否正在运行? |
cr_code |
|
cr_origin |
__doc__ |
文档字符串 |
__name__ |
创建协程的位置,或 |
|
__qualname__ |
限定名称 |
|
__self__ |
内置 |
原始名称 此函数或方法
方法绑定到的实例,或 None
在 3.5 版本中更改: 添加 __qualname__
和 gi_yieldfrom
属性到生成器。
生成器的 __name__
属性现在从函数名称而不是代码名称设置,并且现在可以修改。
-
在 3.7 版本中更改: 添加
cr_origin
属性到协程。 在 3.10 版本中更改: 为函数添加
__builtins__
属性。inspect.getmembers(object[, predicate])¶
getmembers()
仅当参数为类,且这些属性已在元类的自定义__dir__()
中列出时,才会返回元类中定义的类属性。
- inspect.getmembers_static(object[, predicate])¶
返回一个对象的所有成员,以
(name, value)
对的列表形式返回,并按名称排序,不会通过描述符协议、__getattr__ 或 __getattribute__ 触发动态查找。可以选择仅返回满足给定谓词的成员。inspect.getmembers(object[, predicate])¶
getmembers_static()
可能无法检索到 `getmembers` 可以获取的所有成员(如动态创建的属性),并且可能会找到 `getmembers` 无法找到的成员(如引发 AttributeError 的描述符)。在某些情况下,它还可能返回描述符对象而不是实例成员。3.11 版本中新增。
- inspect.getmodulename(path)¶
返回由文件 *path* 命名的模块的名称,不包括封闭包的名称。文件扩展名会与
importlib.machinery.all_suffixes()
中的所有条目进行检查。如果匹配,则返回删除扩展名的最后一个路径组件。否则,返回None
。请注意,此函数*仅*返回实际 Python 模块的有意义的名称 - 可能引用 Python 包的路径仍将返回
None
。在 3.3 版本中更改: 该函数直接基于
importlib
。
- inspect.ismodule(object)¶
如果对象是模块,则返回
True
。
- inspect.isclass(object)¶
如果对象是一个类(内置类或在 Python 代码中创建的类),则返回
True
。
- inspect.ismethod(object)¶
如果对象是在 Python 中编写的绑定方法,则返回
True
。
- inspect.isgeneratorfunction(object)¶
如果对象是 Python 生成器函数,则返回
True
。在 3.8 版本中更改: 用
functools.partial()
包装的函数,如果被包装的函数是 Python 生成器函数,则现在返回True
。在 3.13 版本中更改: 用
functools.partialmethod()
包装的函数,如果被包装的函数是 Python 生成器函数,则现在返回True
。
- inspect.isgenerator(object)¶
如果对象是生成器,则返回
True
。
- inspect.iscoroutinefunction(object)¶
如果对象是 协程函数 (使用
async def
语法定义的函数)、包装 协程函数 的functools.partial()
或用markcoroutinefunction()
标记的同步函数,则返回True
。3.5 版本中新增。
在 3.8 版本中更改: 用
functools.partial()
包装的函数,如果被包装的函数是 协程函数,则现在返回True
。在 3.12 版本中更改: 用
markcoroutinefunction()
标记的同步函数,现在返回True
。在 3.13 版本中更改: 用
functools.partialmethod()
包装的函数,如果被包装的函数是 协程函数,则现在返回True
。
- inspect.markcoroutinefunction(func)¶
如果一个可调用对象不能被
iscoroutinefunction()
检测为 协程函数,则可以使用此装饰器将其标记为 协程函数。如果同步函数返回 协程,并且该函数被传递给需要
iscoroutinefunction()
的 API,则这可能很有用。在可能的情况下,最好使用
async def
函数。也可以接受调用该函数并使用iscoroutine()
测试返回值。3.12 版本中新增。
- inspect.isawaitable(object)¶
如果对象可以在
await
表达式中使用,则返回True
。也可以用来区分基于生成器的协程和普通生成器
import types def gen(): yield @types.coroutine def gen_coro(): yield assert not isawaitable(gen()) assert isawaitable(gen_coro())
3.5 版本中新增。
- inspect.isasyncgenfunction(object)¶
如果对象是异步生成器函数,则返回
True
,例如>>> async def agen(): ... yield 1 ... >>> inspect.isasyncgenfunction(agen) True
3.6 版本中新增。
在 3.8 版本中更改: 用
functools.partial()
包装的函数,如果被包装的函数是异步生成器函数,则现在返回True
。在 3.13 版本中更改: 用
functools.partialmethod()
包装的函数,如果被包装的函数是 协程函数,则现在返回True
。
- inspect.istraceback(object)¶
如果对象是回溯(traceback),则返回
True
。
- inspect.isframe(object)¶
如果对象是帧(frame),则返回
True
。
- inspect.iscode(object)¶
如果对象是代码(code),则返回
True
。
- inspect.isbuiltin(object)¶
如果对象是内置函数或绑定的内置方法,则返回
True
。
- inspect.ismethodwrapper(object)¶
如果对象的类型是
MethodWrapperType
,则返回True
。这些是
MethodWrapperType
的实例,例如__str__()
、__eq__()
和__repr__()
。3.11 版本中新增。
- inspect.isroutine(object)¶
如果对象是用户定义或内置的函数或方法,则返回
True
。
- inspect.isabstract(object)¶
如果对象是抽象基类,则返回
True
。
- inspect.ismethoddescriptor(object)¶
如果对象是方法描述符,但
ismethod()
、isclass()
、isfunction()
或isbuiltin()
返回 False,则返回True
。例如,
int.__add__
就是这种情况。通过此测试的对象具有__get__()
方法,但没有__set__()
方法或__delete__()
方法。除此之外,属性集各不相同。__name__
属性通常是有意义的,而__doc__
通常也是如此。通过描述符实现的方法如果也通过了其他测试之一,则从
ismethoddescriptor()
测试返回False
,这仅仅是因为其他测试承诺提供更多信息 —— 例如,当对象通过ismethod()
时,您可以依赖于拥有__func__
属性(等等)。在 3.13 版本中变更: 此函数不再错误地将具有
__get__()
和__delete__()
但没有__set__()
的对象报告为方法描述符(此类对象是数据描述符,而不是方法描述符)。
- inspect.isdatadescriptor(object)¶
如果对象是数据描述符,则返回
True
。数据描述符具有
__set__
或__delete__
方法。示例包括属性(在 Python 中定义)、getsets 和成员。后两者在 C 中定义,并且有更具体的测试可用于这些类型,这在不同的 Python 实现中是稳健的。通常,数据描述符也将具有__name__
和__doc__
属性(属性、getsets 和成员都具有这两个属性),但这不能保证。
- inspect.isgetsetdescriptor(object)¶
如果对象是 getset 描述符,则返回
True
。CPython 实现细节: getsets 是通过
PyGetSetDef
结构在扩展模块中定义的属性。对于没有此类类型的 Python 实现,此方法将始终返回False
。
- inspect.ismemberdescriptor(object)¶
如果对象是成员描述符,则返回
True
。CPython 实现细节: 成员描述符是通过
PyMemberDef
结构在扩展模块中定义的属性。对于没有此类类型的 Python 实现,此方法将始终返回False
。
检索源代码¶
- inspect.getdoc(object)¶
获取对象的文档字符串,并使用
cleandoc()
进行清理。如果未提供对象的文档字符串,且该对象是类、方法、属性或描述符,则从继承层次结构中检索文档字符串。如果文档字符串无效或缺失,则返回None
。3.5 版本更改: 如果文档字符串未被重写,则现在会继承。
- inspect.getcomments(object)¶
以单个字符串的形式返回对象源代码(对于类、函数或方法)之前紧邻的任何注释行,或者 Python 源文件顶部(如果对象是模块)的注释行。如果对象的源代码不可用,则返回
None
。如果对象是在 C 或交互式 shell 中定义的,则可能会发生这种情况。
- inspect.getmodule(object)¶
尝试猜测对象是在哪个模块中定义的。如果无法确定模块,则返回
None
。
- inspect.getsourcefile(object)¶
返回定义对象的 Python 源代码文件的名称,如果无法识别获取源代码的方法,则返回
None
。如果对象是内置模块、类或函数,这将失败并引发TypeError
异常。
- inspect.getsourcelines(object)¶
返回对象的源代码行列表和起始行号。参数可以是模块、类、方法、函数、回溯、帧或代码对象。源代码以与对象对应的行列表的形式返回,行号指示在原始源文件中找到第一行代码的位置。如果无法检索源代码,则会引发
OSError
异常。如果对象是内置模块、类或函数,则会引发TypeError
异常。
- inspect.getsource(object)¶
返回对象的源代码文本。参数可以是模块、类、方法、函数、回溯、帧或代码对象。源代码以单个字符串的形式返回。如果无法检索源代码,则会引发
OSError
异常。如果对象是内置模块、类或函数,则会引发TypeError
异常。
- inspect.cleandoc(doc)¶
清理与代码块对齐的文档字符串中的缩进。
从第一行中删除所有前导空格。从第二行开始,删除可以统一删除的任何前导空格。随后删除开头和结尾的空行。此外,所有制表符都会扩展为空格。
使用 Signature 对象自省可调用对象¶
在 3.3 版本中添加。
Signature
对象表示可调用对象的调用签名及其返回注解。要检索 Signature
对象,请使用 signature()
函数。
- inspect.signature(callable, *, follow_wrapped=True, globals=None, locals=None, eval_str=False)¶
返回给定 callable 的
Signature
对象。>>> from inspect import signature >>> def foo(a, *, b:int, **kwargs): ... pass >>> sig = signature(foo) >>> str(sig) '(a, *, b: int, **kwargs)' >>> str(sig.parameters['b']) 'b: int' >>> sig.parameters['b'].annotation <class 'int'>
接受各种 Python 可调用对象,从普通函数和类到
functools.partial()
对象。对于使用字符串化注解(
from __future__ import annotations
)在模块中定义的对象,signature()
将尝试使用get_annotations()
自动取消字符串化注解。当解析注解时,globals、locals 和 eval_str 参数会传递到get_annotations()
中;有关如何使用这些参数的说明,请参阅get_annotations()
的文档。如果无法提供签名,则引发
ValueError
异常;如果不支持该类型的对象,则引发TypeError
异常。此外,如果注解是字符串化的,并且 eval_str 不为 False,则调用eval()
来取消get_annotations()
中的注解可能会引发任何类型的异常。函数签名中的斜杠 (/) 表示其之前的参数是仅限位置的参数。有关更多信息,请参阅 有关仅限位置参数的常见问题解答条目。
3.5 版本更改: 添加了 follow_wrapped 参数。传递
False
以获取 callable 的特定签名(不会使用callable.__wrapped__
来解包装饰的可调用对象。)3.10 版本更改: 添加了 globals、locals 和 eval_str 参数。
inspect.getmembers(object[, predicate])¶
某些可调用对象在 Python 的某些实现中可能无法自省。例如,在 CPython 中,某些用 C 定义的内置函数不提供有关其参数的元数据。
CPython 实现细节: 如果传递的对象具有
__signature__
属性,我们可能会使用它来创建签名。确切的语义是实现细节,可能会在未通知的情况下更改。请查阅源代码以了解当前的语义。
- class inspect.Signature(parameters=None, *, return_annotation=Signature.empty)¶
一个
Signature
对象表示一个函数的调用签名及其返回注解。 对于函数接受的每个参数,它会在其parameters
集合中存储一个Parameter
对象。可选的 parameters 参数是一个
Parameter
对象的序列,该序列会经过验证,以检查是否没有重复名称的参数,以及参数的顺序是否正确,即首先是仅限位置的参数,然后是位置或关键字参数,并且具有默认值的参数在没有默认值的参数之后。可选的 return_annotation 参数可以是任意 Python 对象。它表示可调用对象的“返回”注解。
Signature
对象是不可变的。请使用Signature.replace()
或copy.replace()
来创建修改后的副本。在 3.5 版本中更改:
Signature
对象现在是可 pickle 的和 可哈希的。- empty¶
一个特殊的类级别标记,用于指定缺少返回注解。
- parameters¶
一个参数名称到相应
Parameter
对象的有序映射。参数按照严格的定义顺序出现,包括仅限关键字的参数。在 3.7 版本中更改: Python 仅在 3.7 版本之后才明确保证保留仅限关键字参数的声明顺序,尽管实际上此顺序在 Python 3 中始终被保留。
- return_annotation¶
可调用对象的“返回”注解。如果可调用对象没有“返回”注解,则此属性设置为
Signature.empty
。
- bind(*args, **kwargs)¶
创建从位置参数和关键字参数到参数的映射。 如果
*args
和**kwargs
与签名匹配,则返回BoundArguments
,否则引发TypeError
。
- bind_partial(*args, **kwargs)¶
工作方式与
Signature.bind()
相同,但允许省略一些必需的参数(模仿functools.partial()
的行为)。 返回BoundArguments
,或者如果传递的参数与签名不匹配则引发TypeError
。
- replace(*[, parameters][, return_annotation])¶
基于调用
replace()
的实例创建一个新的Signature
实例。 可以传递不同的 parameters 和/或 return_annotation 以覆盖基本签名的相应属性。 要从复制的Signature
中删除return_annotation
,请传入Signature.empty
。>>> def test(a, b): ... pass ... >>> sig = signature(test) >>> new_sig = sig.replace(return_annotation="new return anno") >>> str(new_sig) "(a, b) -> 'new return anno'"
Signature
对象也受泛型函数copy.replace()
支持。
- format(*, max_width=None)¶
创建
Signature
对象的字符串表示形式。如果传递了 max_width,则该方法将尝试将签名放入最多 max_width 个字符的行中。 如果签名长度超过 max_width,则所有参数将位于单独的行上。
3.13 版本中新增。
- classmethod from_callable(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False)¶
返回给定可调用对象 obj 的
Signature
(或其子类)对象。此方法简化了
Signature
的子类化。class MySignature(Signature): pass sig = MySignature.from_callable(sum) assert isinstance(sig, MySignature)
否则,其行为与
signature()
的行为相同。3.5 版本中新增。
3.10 版本更改: 添加了 globals、locals 和 eval_str 参数。
- class inspect.Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty)¶
Parameter
对象是不可变的。 您可以使用Parameter.replace()
或copy.replace()
来创建修改后的副本,而不是修改Parameter
对象。在 3.5 版本中更改: Parameter 对象现在是可 pickle 的和 可哈希的。
- empty¶
一个特殊的类级别标记,用于指定缺少默认值和注解。
- name¶
参数的名称,以字符串形式表示。 该名称必须是有效的 Python 标识符。
CPython 实现细节: CPython 在用于实现推导式和生成器表达式的代码对象上生成形式为
.0
的隐式参数名称。在 3.6 版本中更改: 这些参数名称现在由该模块公开为诸如
implicit0
之类的名称。
- default¶
参数的默认值。如果参数没有默认值,则此属性设置为
Parameter.empty
。
- annotation¶
参数的注解。如果参数没有注解,则此属性设置为
Parameter.empty
。
- kind¶
描述参数值如何绑定到参数。可以通过
Parameter
访问可能的值(例如Parameter.KEYWORD_ONLY
),并支持比较和排序,顺序如下名称
含义
POSITIONAL_ONLY
值必须作为位置参数提供。仅位置参数是指在 Python 函数定义中出现在
/
条目(如果存在)之前的参数。POSITIONAL_OR_KEYWORD
值可以作为关键字参数或位置参数提供(这是 Python 实现的函数的标准绑定行为。)
VAR_POSITIONAL
未绑定到任何其他参数的位置参数的元组。这对应于 Python 函数定义中的
*args
参数。KEYWORD_ONLY
值必须作为关键字参数提供。仅关键字参数是指在 Python 函数定义中出现在
*
或*args
条目之后的参数。VAR_KEYWORD
未绑定到任何其他参数的关键字参数的字典。这对应于 Python 函数定义中的
**kwargs
参数。示例:打印所有没有默认值的仅限关键字的参数
>>> def foo(a, b, *, c, d=10): ... pass >>> sig = signature(foo) >>> for param in sig.parameters.values(): ... if (param.kind == param.KEYWORD_ONLY and ... param.default is param.empty): ... print('Parameter:', param) Parameter: c
- kind.description¶
描述
Parameter.kind
的枚举值。3.8 版本新增。
示例:打印所有参数的描述
>>> def foo(a, b, *, c, d=10): ... pass >>> sig = signature(foo) >>> for param in sig.parameters.values(): ... print(param.kind.description) positional or keyword positional or keyword keyword-only keyword-only
- replace(*[, name][, kind][, default][, annotation])¶
基于调用它的实例创建一个新的
Parameter
实例。要覆盖Parameter
属性,请传递相应的参数。要从Parameter
中删除默认值或/和注解,请传递Parameter.empty
。>>> from inspect import Parameter >>> param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42) >>> str(param) 'foo=42' >>> str(param.replace()) # Will create a shallow copy of 'param' 'foo=42' >>> str(param.replace(default=Parameter.empty, annotation='spam')) "foo: 'spam'"
Parameter
对象也受通用函数copy.replace()
支持。
在 3.4 版本中变更: 在 Python 3.3 中,如果
Parameter
对象的kind
设置为POSITIONAL_ONLY
,则允许将其name
设置为None
。现在不再允许这样做。
- class inspect.BoundArguments¶
Signature.bind()
或Signature.bind_partial()
调用的结果。保存了参数到函数参数的映射。- arguments¶
参数名称到参数值的可变映射。仅包含显式绑定的参数。
arguments
中的更改将反映在args
和kwargs
中。应与
Signature.parameters
结合使用,以进行任何参数处理。inspect.getmembers(object[, predicate])¶
跳过
Signature.bind()
或Signature.bind_partial()
依赖于默认值的参数。但是,如果需要,请使用BoundArguments.apply_defaults()
添加它们。在 3.9 版本中变更:
arguments
现在是dict
类型。以前,它是collections.OrderedDict
类型。
- apply_defaults()¶
为缺失的参数设置默认值。
对于可变位置参数(
*args
),默认值为空元组。对于可变关键字参数(
**kwargs
),默认值为空字典。>>> def foo(a, b='ham', *args): pass >>> ba = inspect.signature(foo).bind('spam') >>> ba.apply_defaults() >>> ba.arguments {'a': 'spam', 'b': 'ham', 'args': ()}
3.5 版本中新增。
def test(a, *, b): ... sig = signature(test) ba = sig.bind(10, b=20) test(*ba.args, **ba.kwargs)
参见
- PEP 362 - 函数签名对象。
详细规范、实现细节和示例。
类和函数¶
- inspect.getclasstree(classes, unique=False)¶
将给定的类列表排列成嵌套列表的层次结构。如果出现嵌套列表,则它包含派生自紧接在该列表之前的条目的类。每个条目是一个 2 元组,包含一个类及其基类元组。如果 unique 参数为 true,则返回的结构中为给定列表中的每个类只显示一个条目。否则,使用多重继承的类及其后代将多次出现。
- inspect.getfullargspec(func)¶
获取 Python 函数的参数名称和默认值。返回一个 命名元组
FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)
args 是位置参数名称的列表。varargs 是
*
参数的名称,如果不支持任意位置参数,则为None
。varkw 是**
参数的名称,如果不支持任意关键字参数,则为None
。defaults 是一个 n 元组,包含与最后 n 个位置参数对应的默认参数值,如果没有定义此类默认值,则为None
。kwonlyargs 是声明顺序中仅限关键字的参数名称列表。kwonlydefaults 是一个字典,将 kwonlyargs 中的参数名称映射到未提供参数时使用的默认值。annotations 是一个将参数名称映射到注解的字典。特殊的键"return"
用于报告函数返回值注解(如果有)。请注意,
signature()
和 Signature 对象 提供了可调用对象自省的推荐 API,并支持在扩展模块 API 中有时会遇到的其他行为(如仅限位置参数)。保留此函数主要是为了在需要保持与 Python 2inspect
模块 API 兼容的代码中使用。在 3.4 版本中更改: 此函数现在基于
signature()
,但仍然忽略__wrapped__
属性,并在绑定方法的签名输出中包含已绑定的第一个参数。在 3.6 版本中更改: 此方法之前在 Python 3.5 中被记录为已弃用,建议使用
signature()
,但该决定已被撤销,以便为从遗留的getargspec()
API 迁移的单源 Python 2/3 代码恢复一个明确支持的标准接口。在 3.7 版本中更改: Python 仅在 3.7 版本之后才明确保证保留仅限关键字参数的声明顺序,尽管实际上此顺序在 Python 3 中始终被保留。
- inspect.getargvalues(frame)¶
获取有关传递到特定帧的参数的信息。返回一个 命名元组
ArgInfo(args, varargs, keywords, locals)
。args 是参数名称的列表。varargs 和 keywords 是*
和**
参数的名称,或者为None
。locals 是给定帧的局部变量字典。inspect.getmembers(object[, predicate])¶
此函数在 Python 3.5 中被意外标记为已弃用。
- inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue])¶
从
getargvalues()
返回的四个值格式化一个漂亮的参数规范。format* 参数是相应的可选格式化函数,这些函数被调用以将名称和值转换为字符串。inspect.getmembers(object[, predicate])¶
此函数在 Python 3.5 中被意外标记为已弃用。
- inspect.getmro(cls)¶
返回一个元组,包含类 cls 的基类,包括 cls,按照方法解析顺序排列。此元组中没有类出现多次。请注意,方法解析顺序取决于 cls 的类型。除非使用非常特殊的、用户定义的元类型,否则 cls 将是元组的第一个元素。
- inspect.getcallargs(func, /, *args, **kwds)¶
将 args 和 kwds 绑定到 Python 函数或方法 func 的参数名称,就像使用它们调用一样。对于绑定方法,还将第一个参数(通常命名为
self
)绑定到关联的实例。返回一个字典,将参数名称(包括*
和**
参数的名称,如果有)映射到它们在 args 和 kwds 中的值。如果错误地调用 func,即当func(*args, **kwds)
由于不兼容的签名而引发异常时,会引发相同类型且相同或相似消息的异常。例如>>> from inspect import getcallargs >>> def f(a, b=1, *pos, **named): ... pass ... >>> getcallargs(f, 1, 2, 3) == {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)} True >>> getcallargs(f, a=2, x=4) == {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()} True >>> getcallargs(f) Traceback (most recent call last): ... TypeError: f() missing 1 required positional argument: 'a'
在 3.2 版本中添加。
自 3.5 版本起已弃用: 请改用
Signature.bind()
和Signature.bind_partial()
。
- inspect.getclosurevars(func)¶
获取 Python 函数或方法 func 中对外部名称的引用与其当前值的映射。返回一个 命名元组
ClosureVars(nonlocals, globals, builtins, unbound)
。nonlocals 将引用的名称映射到词法闭包变量,globals 映射到函数的模块全局变量,builtins 映射到从函数体可见的内置函数。unbound 是函数中引用的一组名称,这些名称在当前模块全局变量和内置函数中无法解析。如果 func 不是 Python 函数或方法,则会引发
TypeError
。在 3.3 版本中添加。
- inspect.unwrap(func, *, stop=None)¶
获取 func 包装的对象。它遵循
__wrapped__
属性的链,返回链中的最后一个对象。stop 是一个可选的回调函数,它接受包装器链中的对象作为其唯一参数,如果回调函数返回真值,则允许提前终止解包。如果回调函数永远不返回真值,则像往常一样返回链中的最后一个对象。例如,
signature()
使用它来停止解包,如果链中的任何对象定义了__signature__
属性。如果遇到循环,则会引发
ValueError
。在 3.4 版本中添加。
- inspect.get_annotations(obj, *, globals=None, locals=None, eval_str=False)¶
计算对象的注解字典。
obj
可以是可调用对象、类或模块。传递任何其他类型的对象会引发TypeError
。返回一个字典。
get_annotations()
每次调用都会返回一个新的字典;在同一对象上调用两次将返回两个不同但等效的字典。此函数为您处理以下几个细节:
如果
eval_str
为 true,则类型为str
的值将使用eval()
进行去字符串化。这旨在与字符串化的注解一起使用(from __future__ import annotations
)。如果
obj
没有注解字典,则返回一个空字典。(函数和方法始终具有注解字典;类、模块和其他类型的可调用对象可能没有。)忽略类上的继承注解。如果类没有自己的注解字典,则返回一个空字典。
所有对对象成员和字典值的访问都使用
getattr()
和dict.get()
来确保安全。始终、始终、始终返回一个新创建的字典。
eval_str
控制是否将str
类型的值替换为对这些值调用eval()
的结果。如果 eval_str 为 true,则会对类型为
str
的值调用eval()
。(请注意,get_annotations
不会捕获异常;如果eval()
引发异常,它将展开堆栈,跳过get_annotations
调用。)如果 eval_str 为 false(默认值),则类型为
str
的值保持不变。
globals
和locals
会传递给eval()
;有关更多信息,请参阅eval()
的文档。如果globals
或locals
为None
,此函数可能会根据type(obj)
将该值替换为上下文特定的默认值。如果
obj
是一个模块,则globals
默认为obj.__dict__
。如果
obj
是一个类,则globals
默认为sys.modules[obj.__module__].__dict__
,locals
默认为obj
类命名空间。如果
obj
是一个可调用对象,则globals
默认为obj.__globals__
,但如果obj
是一个包装过的函数(使用functools.update_wrapper()
),则会先将其解包。
调用
get_annotations
是访问任何对象的 annotations 字典的最佳实践。有关注释最佳实践的更多信息,请参阅 注释最佳实践。3.10 版本中新增。
解释器堆栈¶
以下一些函数返回 FrameInfo
对象。为了向后兼容,这些对象允许对除 positions
之外的所有属性执行类似元组的操作。此行为被视为已弃用,将来可能会被删除。
- class inspect.FrameInfo¶
-
- filename¶
与此记录对应的帧所执行的代码关联的文件名。
- lineno¶
与此记录对应的帧所执行的代码关联的当前行号。
- function¶
与此记录对应的帧所执行的函数名称。
- code_context¶
来自此记录对应的帧所执行的源代码的上下文行列表。
- index¶
在
code_context
列表中当前执行的行的索引。
- positions¶
一个
dis.Positions
对象,其中包含与此记录对应的帧所执行的指令关联的起始行号、结束行号、起始列偏移量和结束列偏移量。
在 3.11 版本中更改:
FrameInfo
现在是一个类实例(与之前的 命名元组 向后兼容)。
- class inspect.Traceback¶
- filename¶
与此回溯对应的帧所执行的代码关联的文件名。
- lineno¶
与此回溯对应的帧所执行的代码关联的当前行号。
- function¶
与此回溯对应的帧所执行的函数名称。
- code_context¶
来自此回溯对应的帧所执行的源代码的上下文行列表。
- index¶
在
code_context
列表中当前执行的行的索引。
- positions¶
一个
dis.Positions
对象,其中包含与此回溯对应的帧所执行的指令关联的起始行号、结束行号、起始列偏移量和结束列偏移量。
在 3.11 版本中更改:
Traceback
现在是一个类实例(与之前的 命名元组 向后兼容)。
inspect.getmembers(object[, predicate])¶
保留对帧对象的引用(如这些函数返回的帧记录的第一个元素中所示)可能会导致您的程序创建引用循环。一旦创建了引用循环,即使启用了 Python 的可选循环检测器,也可以从形成循环的对象访问的所有对象的生命周期都会变得更长。如果必须创建此类循环,请务必确保显式断开它们,以避免对象的延迟销毁和内存消耗增加的情况发生。
尽管循环检测器会捕获这些循环,但可以通过在 finally
子句中删除循环来确定帧(和局部变量)的销毁时间。如果 Python 编译时禁用了循环检测器或使用 gc.disable()
,这也非常重要。例如
def handle_stackframe_without_leak():
frame = inspect.currentframe()
try:
# do something with the frame
finally:
del frame
如果您想保留帧(例如稍后打印回溯),您还可以使用 frame.clear()
方法来打破引用循环。
大多数这些函数支持的可选 context 参数指定要返回的上下文行数,这些行数围绕当前行居中。
- inspect.getframeinfo(frame, context=1)¶
获取有关帧或回溯对象的信息。返回一个
Traceback
对象。在 3.11 版本中更改: 返回一个
Traceback
对象,而不是一个命名元组。
- inspect.getouterframes(frame, context=1)¶
获取一个帧及其所有外部帧的
FrameInfo
对象列表。这些帧表示导致创建 frame 的调用。返回列表中的第一个条目表示 frame;最后一个条目表示 frame 堆栈上的最外层调用。在 3.5 版本中变更: 返回一个 命名元组
FrameInfo(frame, filename, lineno, function, code_context, index)
的列表。在 3.11 版本中变更: 返回一个
FrameInfo
对象的列表。
- inspect.getinnerframes(traceback, context=1)¶
获取一个回溯的帧及其所有内部帧的
FrameInfo
对象列表。这些帧表示作为 frame 的结果进行的调用。列表中的第一个条目表示 traceback;最后一个条目表示引发异常的位置。在 3.5 版本中变更: 返回一个 命名元组
FrameInfo(frame, filename, lineno, function, code_context, index)
的列表。在 3.11 版本中变更: 返回一个
FrameInfo
对象的列表。
- inspect.currentframe()¶
返回调用者的堆栈帧的帧对象。
CPython 实现细节:此函数依赖于解释器中的 Python 堆栈帧支持,这不能保证在 Python 的所有实现中都存在。如果在没有 Python 堆栈帧支持的实现中运行,则此函数返回
None
。
静态获取属性¶
在获取或检查属性是否存在时,getattr()
和 hasattr()
都会触发代码执行。像属性这样的描述符将被调用,并且可能会调用 __getattr__()
和 __getattribute__()
。
对于需要被动内省(如文档工具)的情况,这可能会很不方便。getattr_static()
具有与 getattr()
相同的签名,但在获取属性时会避免执行代码。
- inspect.getattr_static(obj, attr, default=None)¶
检索属性,而不会通过描述符协议、
__getattr__()
或__getattribute__()
触发动态查找。注意:此函数可能无法检索 `getattr` 可以获取的所有属性(如动态创建的属性),并且可能会找到 `getattr` 无法找到的属性(如引发 `AttributeError` 的描述符)。它还可能返回描述符对象,而不是实例成员。
如果实例的
__dict__
被另一个成员(例如属性)所遮蔽,则此函数将无法找到实例成员。在 3.2 版本中添加。
getattr_static()
不会解析描述符,例如用 C 实现的对象上的槽描述符或 getset 描述符。将返回描述符对象,而不是底层属性。
您可以使用以下代码处理这些问题。请注意,对于任意的 getset 描述符,调用这些描述符可能会触发代码执行
# example code for resolving the builtin descriptor types
class _foo:
__slots__ = ['foo']
slot_descriptor = type(_foo.foo)
getset_descriptor = type(type(open(__file__)).name)
wrapper_descriptor = type(str.__dict__['__add__'])
descriptor_types = (slot_descriptor, getset_descriptor, wrapper_descriptor)
result = getattr_static(some_object, 'foo')
if type(result) in descriptor_types:
try:
result = result.__get__()
except AttributeError:
# descriptors can raise AttributeError to
# indicate there is no underlying value
# in which case the descriptor itself will
# have to do
pass
生成器、协程和异步生成器的当前状态¶
在实现协程调度器以及其他生成器高级用法时,确定生成器当前是否正在执行、是否正在等待开始或恢复执行,或者是否已终止会很有用。getgeneratorstate()
允许轻松确定生成器的当前状态。
- inspect.getgeneratorstate(generator)¶
获取生成器迭代器的当前状态。
可能的状态有
GEN_CREATED:等待开始执行。
GEN_RUNNING:当前正在由解释器执行。
GEN_SUSPENDED:当前在 `yield` 表达式处挂起。
GEN_CLOSED:执行已完成。
在 3.2 版本中添加。
- inspect.getcoroutinestate(coroutine)¶
获取协程对象的当前状态。此函数旨在与通过
async def
函数创建的协程对象一起使用,但会接受任何具有cr_running
和cr_frame
属性的类协程对象。可能的状态有
CORO_CREATED:等待开始执行。
CORO_RUNNING:当前正在由解释器执行。
CORO_SUSPENDED:当前在 `await` 表达式处挂起。
CORO_CLOSED:执行已完成。
3.5 版本中新增。
- inspect.getasyncgenstate(agen)¶
获取异步生成器对象的当前状态。此函数旨在与通过使用
yield
语句的async def
函数创建的异步迭代器对象一起使用,但会接受任何具有ag_running
和ag_frame
属性的类异步生成器对象。可能的状态有
AGEN_CREATED:等待开始执行。
AGEN_RUNNING:当前正在由解释器执行。
AGEN_SUSPENDED:当前在 `yield` 表达式处挂起。
AGEN_CLOSED:执行已完成。
3.12 版本中新增。
还可以查询生成器的当前内部状态。这主要用于测试目的,以确保内部状态按预期更新
- inspect.getgeneratorlocals(generator)¶
获取 generator 中实时局部变量到其当前值的映射。返回一个字典,该字典将变量名映射到值。这等效于在生成器的正文中调用
locals()
,并应用所有相同的警告。如果generator是一个没有当前关联帧的生成器,则返回一个空字典。 如果generator不是Python生成器对象,则会引发
TypeError
。CPython 实现细节: 此函数依赖于生成器暴露用于内省的 Python 堆栈帧,这不能保证在 Python 的所有实现中都存在。 在这种情况下,此函数将始终返回一个空字典。
在 3.3 版本中添加。
- inspect.getcoroutinelocals(coroutine)¶
此函数类似于
getgeneratorlocals()
,但适用于由async def
函数创建的协程对象。3.5 版本中新增。
- inspect.getasyncgenlocals(agen)¶
此函数类似于
getgeneratorlocals()
,但适用于由使用yield
语句的async def
函数创建的异步生成器对象。3.12 版本中新增。
代码对象位标志¶
Python 代码对象具有 co_flags
属性,它是以下标志的位图
- inspect.CO_OPTIMIZED¶
代码对象已使用快速局部变量进行优化。
- inspect.CO_VARARGS¶
代码对象具有可变的位置参数(类似于
*args
)。
- inspect.CO_VARKEYWORDS¶
代码对象具有可变的关键字参数(类似于
**kwargs
)。
- inspect.CO_NESTED¶
当代码对象是嵌套函数时,会设置此标志。
- inspect.CO_GENERATOR¶
当代码对象是生成器函数时,会设置此标志,即执行代码对象时返回生成器对象。
缓冲区标志¶
- class inspect.BufferFlags¶
这是一个
enum.IntFlag
,表示可以传递给实现 缓冲区协议 的对象的__buffer__()
方法的标志。这些标志的含义在 缓冲区请求类型 中进行了解释。
- SIMPLE¶
- WRITABLE¶
- FORMAT¶
- ND¶
- STRIDES¶
- C_CONTIGUOUS¶
- F_CONTIGUOUS¶
- ANY_CONTIGUOUS¶
- INDIRECT¶
- CONTIG¶
- CONTIG_RO¶
- STRIDED¶
- STRIDED_RO¶
- RECORDS¶
- RECORDS_RO¶
- FULL¶
- FULL_RO¶
- READ¶
- WRITE¶
3.12 版本中新增。
命令行界面¶
inspect
模块还提供了从命令行进行基本内省的功能。
默认情况下,接受模块的名称并打印该模块的源代码。 可以通过附加冒号和目标对象的限定名称来打印模块内的类或函数。
- --details¶
打印有关指定对象的信息,而不是源代码