inspect
— 检查实时对象¶
源代码: Lib/inspect.py
inspect
模块提供了几个有用的函数,用于帮助获取关于模块、类、方法、函数、回溯、帧对象和代码对象等实时对象的信息。例如,它可以帮助你检查类的内容、检索方法的源代码、提取并格式化函数的参数列表,或者获取显示详细回溯所需的所有信息。
此模块提供四种主要服务:类型检查、获取源代码、检查类和函数以及检查解释器堆栈。
类型和成员¶
getmembers()
函数检索对象的成员,例如类或模块。名称以“is”开头的函数主要作为 getmembers()
的第二个参数的便捷选择。它们还可以帮助你确定何时可以预期找到以下特殊属性(有关模块属性,请参阅模块对象上与导入相关的属性)
类型 |
属性 |
描述 |
---|---|---|
类 |
__doc__ |
文档字符串 |
__name__ |
定义此类的名称 |
|
__qualname__ |
限定名称 |
|
__module__ |
定义此类的模块名称 |
|
__type_params__ |
一个包含泛型类的类型参数的元组 |
|
方法 |
__doc__ |
文档字符串 |
__name__ |
定义此方法的名称 |
|
__qualname__ |
限定名称 |
|
__func__ |
包含方法实现的函数对象 |
|
__self__ |
此方法绑定的实例,或 |
|
__module__ |
定义此方法的模块名称 |
|
函数 |
__doc__ |
文档字符串 |
__name__ |
定义此函数的名称 |
|
__qualname__ |
限定名称 |
|
__code__ |
包含已编译函数字节码的代码对象 |
|
__defaults__ |
位置参数或关键字参数的任何默认值的元组 |
|
__kwdefaults__ |
仅关键字参数的任何默认值的映射 |
|
__globals__ |
定义此函数的全局命名空间 |
|
__builtins__ |
内置命名空间 |
|
__annotations__ |
参数名称到注解的映射; |
|
__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 |
返回拥有此帧的生成器或协程对象,如果帧是常规函数则返回 |
|
f_trace |
此帧的跟踪函数,或 |
|
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_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 |
由 |
|
异步生成器 |
__name__ |
名称 |
__qualname__ |
限定名称 |
|
ag_await |
正在等待的对象,或 |
|
ag_frame |
帧 |
|
ag_running |
生成器是否正在运行? |
|
ag_code |
code |
|
协程 |
__name__ |
名称 |
__qualname__ |
限定名称 |
|
cr_await |
正在等待的对象,或 |
|
cr_frame |
帧 |
|
cr_running |
协程是否正在运行? |
|
cr_code |
code |
|
cr_origin |
协程的创建位置,或 |
|
内置 |
__doc__ |
文档字符串 |
__name__ |
此函数或方法的原始名称 |
|
__qualname__ |
限定名称 |
|
__self__ |
方法绑定的实例,或 |
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.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.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)¶
如果对象是回溯,则返回
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.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, 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
中的更改将反映在args
和kwargs
中。应与
Signature.parameters
结合使用,以进行任何参数处理。备注
对于
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 参数为真,则返回的结构中给定列表中的每个类只出现一个条目。否则,使用多重继承的类及其子类将多次出现。
- 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 Object 提供了可调用自省的推荐 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 是给定帧的局部变量字典。备注
此函数在 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)¶
将 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, format=annotationlib.Format.VALUE)¶
计算对象的注释字典。
这是
annotationlib.get_annotations()
的别名;有关更多信息,请参阅该函数的文档。注意
此函数可能会执行注释中包含的任意代码。有关更多信息,请参阅 自省注释的安全隐患。
在 3.10 版本加入。
3.14 版本中已更改: 此函数现在是
annotationlib.get_annotations()
的别名。将其作为inspect.get_annotations
调用将继续有效。
解释器堆栈¶
以下某些函数返回 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
现在是一个类实例(与之前的 命名元组 兼容)。
备注
保留对帧对象的引用(如这些函数返回的帧记录的第一个元素中所示)可能导致您的程序创建引用循环。一旦创建了引用循环,即使启用了 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¶
当代码对象是生成器函数时,此标志会被设置,即当代码对象执行时会返回一个生成器对象。
- inspect.CO_ITERABLE_COROUTINE¶
此标志用于将生成器转换为基于生成器的协程。带有此标志的生成器对象可以在
await
表达式中使用,并且可以yield from
协程对象。有关更多详细信息,请参阅 PEP 492。在 3.5 版本加入。
- inspect.CO_ASYNC_GENERATOR¶
当代码对象是异步生成器函数时,此标志会被设置。当代码对象执行时,它会返回一个异步生成器对象。有关更多详细信息,请参阅 PEP 525。
在 3.6 版本加入。
- 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¶
打印有关指定对象的信息而不是源代码