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__ |
定义此函数的模块名称 |
|
回溯 |
tb_frame |
此级别的帧对象 |
tb_lasti |
字节码中最后尝试的指令的索引 |
|
tb_lineno |
Python 源代码中的当前行号 |
|
tb_next |
下一个内部回溯对象(由此级别调用) |
|
帧 |
f_back |
下一个外部帧对象(此帧的调用者) |
f_builtins |
此帧看到的内置命名空间 |
|
f_code |
在此帧中执行的代码对象 |
|
f_globals |
此帧看到的全局命名空间 |
|
f_lasti |
字节码中最后尝试的指令的索引 |
|
f_lineno |
Python 源代码中的当前行号 |
|
f_locals |
此帧看到的局部命名空间 |
|
f_trace |
此帧的跟踪函数,或 |
|
代码 |
co_argcount |
参数数量(不包括仅关键字参数、* 或 ** 参数) |
co_code |
原始已编译字节码的字符串 |
|
co_cellvars |
单元格变量名称的元组(由包含范围引用) |
|
co_consts |
字节码中使用的常量的元组 |
|
co_filename |
创建此代码对象的源文件名 |
|
co_firstlineno |
Python 源代码中第一行的行号 |
|
co_flags |
|
|
co_lnotab |
行号到字节码索引的编码映射 |
|
co_freevars |
自由变量名称的元组(通过函数的闭包引用) |
|
co_posonlyargcount |
仅位置参数的数量 |
|
co_kwonlyargcount |
仅关键字参数的数量(不包括 ** 参数) |
|
co_name |
定义此代码对象的名称 |
|
co_qualname |
定义此代码对象的完全限定名称 |
|
co_names |
除参数和函数局部变量之外的名称元组 |
|
co_nlocals |
局部变量的数量 |
|
co_stacksize |
虚拟机堆栈空间要求 |
|
co_varnames |
参数和局部变量名称元组 |
|
生成器 |
__name__ |
名称 |
__qualname__ |
限定名称 |
|
gi_frame |
帧 |
|
gi_running |
生成器是否正在运行? |
|
gi_code |
代码 |
|
gi_yieldfrom |
由 |
|
异步生成器 |
__name__ |
名称 |
__qualname__ |
限定名称 |
|
ag_await |
正在等待的对象,或 |
|
ag_frame |
帧 |
|
ag_running |
生成器是否正在运行? |
|
ag_code |
代码 |
|
协程 |
__name__ |
名称 |
__qualname__ |
限定名称 |
|
cr_await |
正在等待的对象,或 |
|
cr_frame |
帧 |
|
cr_running |
协程是否正在运行? |
|
cr_code |
代码 |
|
cr_origin |
协程创建的位置,或 |
|
内置 |
__doc__ |
文档字符串 |
__name__ |
此函数或方法的原始名称 |
|
__qualname__ |
限定名称 |
|
__self__ |
方法绑定的实例,或 |
3.5 版中已更改: 为生成器添加 __qualname__
和 gi_yieldfrom
属性。
生成器的 __name__
属性现在从函数名称设置,而不是代码名称,现在可以对其进行修改。
3.7 版中已更改: 为协程添加 cr_origin
属性。
3.10 版中已更改: 为函数添加 __builtins__
属性。
- inspect.getmembers(object[, predicate])¶
以按名称排序的
(name, value)
对列表形式返回对象的所有成员。如果提供了可选的 predicate 参数(该参数将使用每个成员的value
对象调用),则仅包含谓词返回真值的成员。注意
getmembers()
仅在参数为类且这些属性已列在元类的自定义__dir__()
中时,才会返回元类中定义的类属性。
- inspect.getmembers_static(object[, predicate])¶
以按名称排序的
(name, value)
对列表形式返回对象的所有成员,而不会通过描述符协议、__getattr__ 或 __getattribute__ 触发动态查找。或者,仅返回满足给定谓词的成员。注意
getmembers_static()
可能无法检索 getmembers 可以获取的所有成员(例如动态创建的属性),并且可能找到 getmembers 无法找到的成员(例如引发 AttributeError 的描述符)。在某些情况下,它还可以返回描述符对象而不是实例成员。在版本 3.11 中添加。
- inspect.getmodulename(path)¶
返回文件 path 命名的模块的名称,不包括封闭包的名称。文件扩展名将与
importlib.machinery.all_suffixes()
中的所有条目进行比较。如果匹配,则返回最终路径组件,并删除扩展名。否则,返回None
。请注意,此函数仅为实际 Python 模块返回有意义的名称 - 可能引用 Python 包的路径仍将返回
None
。在版本 3.3 中更改:此函数直接基于
importlib
。
- inspect.ismodule(object)¶
如果对象是模块,则返回
True
。
- inspect.isclass(object)¶
如果对象是类,无论是在 Python 代码中创建的还是内置的,则返回
True
。
- inspect.ismethod(object)¶
如果对象是用 Python 编写的绑定方法,则返回
True
。
- inspect.isgeneratorfunction(object)¶
如果对象是 Python 生成器函数,则返回
True
。在 3.8 版本中已更改: 如果包装函数是 Python 生成器函数,则现在用
functools.partial()
包装的函数将返回True
。
- inspect.isgenerator(object)¶
如果对象是生成器,则返回
True
。
- inspect.iscoroutinefunction(object)¶
如果对象是 协程函数(使用
async def
语法定义的函数)、用functools.partial()
包装的 协程函数 或用markcoroutinefunction()
标记的同步函数,则返回True
。在 3.5 版本中添加。
在 3.8 版本中已更改: 如果包装函数是 协程函数,则现在用
functools.partial()
包装的函数将返回True
。在 3.12 版本中已更改: 现在用
markcoroutinefunction()
标记的同步函数将返回True
。
- inspect.markcoroutinefunction(func)¶
如果可调用对象不会被
iscoroutinefunction()
检测到,则用此装饰器将其标记为 协程函数。如果将同步函数传递给需要
iscoroutinefunction()
的 API,则此函数可能对返回 协程 的同步函数有用。如果可能,优先使用
async def
函数。也可以调用该函数,并使用iscoroutine()
测试返回值。在 3.12 版本中添加。
- inspect.isawaitable(object)¶
如果对象可以在
await
表达式中使用,则返回True
。还可以用于区分基于生成器的协程和常规生成器
import types def gen(): yield @types.coroutine def gen_coro(): yield assert not isawaitable(gen()) assert isawaitable(gen_coro())
在 3.5 版本中添加。
- inspect.isasyncgenfunction(object)¶
如果对象是 异步生成器 函数,则返回
True
,例如>>> async def agen(): ... yield 1 ... >>> inspect.isasyncgenfunction(agen) True
在 3.6 版本中添加。
在 3.8 版本中更改:如果包装的函数是 异步生成器 函数,则用
functools.partial()
包装的函数现在返回True
。
- inspect.istraceback(object)¶
如果对象是回溯,则返回
True
。
- inspect.isframe(object)¶
如果对象是帧,则返回
True
。
- inspect.iscode(object)¶
如果对象是代码,则返回
True
。
- inspect.isbuiltin(object)¶
如果对象是内置函数或绑定内置方法,则返回
True
。
- inspect.ismethodwrapper(object)¶
如果对象的类型是
MethodWrapperType
,则返回True
。这些是
MethodWrapperType
的实例,例如__str__()
、__eq__()
和__repr__()
。在版本 3.11 中添加。
- inspect.isroutine(object)¶
如果对象是用户定义或内置函数或方法,则返回
True
。
- inspect.isabstract(object)¶
如果对象是抽象基类,则返回
True
。
- inspect.ismethoddescriptor(object)¶
如果对象是方法描述符,但不是
ismethod()
、isclass()
、isfunction()
或isbuiltin()
为 true,则返回True
。例如,
int.__add__
便是如此。通过此测试的对象有__get__()
方法,但没有__set__()
方法,但除此之外,属性集是不同的。__name__
属性通常是明智的,而__doc__
通常也是如此。通过描述符实现的方法,如果也通过其他测试之一,则从
ismethoddescriptor()
测试返回False
,仅仅是因为其他测试承诺更多——例如,当对象通过ismethod()
时,您可以依赖于有__func__
属性(等等)。
- inspect.isdatadescriptor(object)¶
如果对象是数据描述符,则返回
True
。数据描述符有
__set__
或__delete__
方法。示例包括属性(在 Python 中定义)、getset 和成员。后两者在 C 中定义,并且有更具体的测试可用于这些类型,这在 Python 实现中是可靠的。通常,数据描述符还将有__name__
和__doc__
属性(属性、getset 和成员都有这两个属性),但这并不能得到保证。
- inspect.isgetsetdescriptor(object)¶
如果对象是 getset 描述符,则返回
True
。CPython 实现细节:getset 是通过
PyGetSetDef
结构在扩展模块中定义的属性。对于没有此类类型的 Python 实现,此方法将始终返回False
。
- inspect.ismemberdescriptor(object)¶
如果对象是成员描述符,则返回
True
。CPython 实现细节:成员描述符是通过
PyMemberDef
结构在扩展模块中定义的属性。对于没有此类类型的 Python 实现,此方法将始终返回False
。
检索源代码¶
- inspect.getdoc(object)¶
获取对象的文档字符串,用
cleandoc()
清理。如果未提供对象的文档字符串,并且该对象是一个类、一个方法、一个属性或一个描述符,则从继承层次结构中检索文档字符串。如果文档字符串无效或缺失,则返回None
。3.5 版中已更改: 如果未覆盖,现在将继承文档字符串。
- inspect.getcomments(object)¶
以单个字符串形式返回紧接在对象的源代码(对于类、函数或方法)之前或在 Python 源文件顶部(如果对象是模块)的任何注释行。如果对象的源代码不可用,则返回
None
。如果对象已在 C 或交互式 shell 中定义,则可能会发生这种情况。
- inspect.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)¶
返回给定可调用对象一个
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,则get_annotations()
中取消字符串化注释的eval()
调用可能会引发任何类型的异常。函数签名中的斜杠 (/) 表示其之前的参数是仅限位置的。有关更多信息,请参阅 仅限位置的参数常见问题解答条目。
在 3.5 版中更改: 添加了 follow_wrapped 参数。传递
False
以专门获取 可调用对象 的签名(callable.__wrapped__
将不会用于解包装饰的可调用对象。)在 3.10 版中更改: 添加了 globals、locals 和 eval_str 参数。
注意
在某些 Python 实现中,某些可调用对象可能无法内省。例如,在 CPython 中,某些用 C 定义的内置函数不提供有关其参数的元数据。
CPython 实现细节:如果传递的对象具有
__signature__
属性,我们可能会使用它来创建签名。确切的语义是实现细节,可能会发生未宣布的更改。有关当前语义,请查阅源代码。
- class inspect.Signature(parameters=None, *, return_annotation=Signature.empty)¶
一个
Signature
对象表示一个函数的调用签名及其返回注释。对于函数接受的每个参数,它都会在parameters
集合中存储一个Parameter
对象。可选的 parameters 参数是
Parameter
对象的序列,它经过验证以检查是否存在具有重复名称的参数,以及参数是否按正确的顺序排列,即仅限位置的参数排在第一位,然后是位置或关键字参数,具有默认值的参数紧随不具有默认值的参数之后。可选的 return_annotation 参数可以是任意 Python 对象。它表示可调用对象的“返回”注释。
Signature
对象是不可变的。使用Signature.replace()
来制作一个修改后的副本。在 3.5 版本中更改:
Signature
对象现在可被腌制和 哈希。- empty¶
一个特殊的类级别标记,用于指定没有返回注释。
- parameters¶
一个有序映射,将参数的名称映射到相应的
Parameter
对象。参数按严格的定义顺序出现,包括仅限关键字的参数。在 3.7 版本中更改:Python 仅明确保证它保留了仅限关键字的参数的声明顺序(从 3.7 版本开始),尽管在实践中,此顺序在 Python 3 中始终保留。
- return_annotation¶
可调用对象的“返回”注释。如果可调用对象没有“返回”注释,则此属性将设置为
Signature.empty
。
- bind(*args, **kwargs)¶
创建从位置参数和关键字参数到参数的映射。如果
*args
和**kwargs
匹配签名,则返回BoundArguments
,否则引发TypeError
。
- bind_partial(*args, **kwargs)¶
与
Signature.bind()
的工作方式相同,但允许省略一些必需参数(模拟functools.partial()
行为)。如果传递的参数与签名不匹配,则返回BoundArguments
,否则引发TypeError
。
- replace(*[, parameters][, return_annotation])¶
基于调用
replace()
的实例创建一个新的Signature
实例。可以传递不同的 parameters 和/或 return_annotation 来覆盖基本签名的相应属性。要从复制的Signature
中删除return_annotation
,请传入Signature.empty
。>>> def test(a, b): ... pass ... >>> sig = signature(test) >>> new_sig = sig.replace(return_annotation="new return anno") >>> str(new_sig) "(a, b) -> 'new return anno'"
- classmethod from_callable(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False)¶
为给定的可调用对象 obj 返回
Signature
(或其子类)对象。此方法简化了
Signature
的子类化。class MySignature(Signature): pass sig = MySignature.from_callable(sum) assert isinstance(sig, MySignature)
否则,其行为与
signature()
相同。在 3.5 版本中添加。
在 3.10 版中更改: 添加了 globals、locals 和 eval_str 参数。
- 类 inspect.Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty)¶
Parameter
对象是不可变的。您可以使用Parameter.replace()
创建修改后的副本,而不是修改Parameter
对象。在版本 3.5 中更改:Parameter 对象现在可进行腌制和 哈希。
- empty¶
一个特殊的类级别标记,用于指定不存在默认值和注释。
- name¶
作为字符串的参数名称。该名称必须是有效的 Python 标识符。
CPython 实现细节:CPython 在用于实现解析和生成器表达式的代码对象上生成形式为
.0
的隐式参数名称。在版本 3.6 中更改:这些参数名称现在通过此模块公开,如
implicit0
等名称。
- default¶
参数的默认值。如果参数没有默认值,则此属性设置为
Parameter.empty
。
- annotation¶
参数的注释。如果参数没有注释,则此属性设置为
Parameter.empty
。
- kind¶
描述如何将参数值绑定到参数。可以通过
Parameter
访问可能的值(如Parameter.KEYWORD_ONLY
),并支持比较和排序,按以下顺序名称
含义
POSITIONAL_ONLY
值必须作为位置参数提供。仅位置参数是指在 Python 函数定义中出现在
/
条目(如果存在)之前的参数。POSITIONAL_OR_KEYWORD
值可以作为关键字或位置参数提供(这是 Python 中实现的函数的标准绑定行为。)
VAR_POSITIONAL
未绑定到任何其他参数的位置参数的元组。这对应于 Python 函数定义中的
*args
参数。KEYWORD_ONLY
值必须作为关键字参数提供。仅关键字参数是指在 Python 函数定义中出现在
*
或*args
条目之后的参数。VAR_KEYWORD
未绑定到任何其他参数的关键字参数的字典。这对应于 Python 函数定义中的
**kwargs
参数。示例:打印所有没有默认值的仅关键字参数
>>> def foo(a, b, *, c, d=10): ... pass >>> sig = signature(foo) >>> for param in sig.parameters.values(): ... if (param.kind == param.KEYWORD_ONLY and ... param.default is param.empty): ... print('Parameter:', param) Parameter: c
- kind.description¶
描述
Parameter.kind
的枚举值。在版本 3.8 中添加。
示例:打印所有参数的说明
>>> def foo(a, b, *, c, d=10): ... pass >>> sig = signature(foo) >>> for param in sig.parameters.values(): ... print(param.kind.description) positional or keyword positional or keyword keyword-only keyword-only
- replace(*[, name][, kind][, default][, annotation])¶
基于调用替换实例的实例创建一个新的
Parameter
实例。要覆盖Parameter
属性,请传递相应的参数。要从Parameter
中删除默认值或/和注释,请传递Parameter.empty
。>>> from inspect import Parameter >>> param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42) >>> str(param) 'foo=42' >>> str(param.replace()) # Will create a shallow copy of 'param' 'foo=42' >>> str(param.replace(default=Parameter.empty, annotation='spam')) "foo: 'spam'"
在版本 3.4 中更改: 在 Python 3.3 中,如果
kind
设置为POSITIONAL_ONLY
,则允许Parameter
对象将name
设置为None
。不再允许这样做。
- class inspect.BoundArguments¶
Signature.bind()
或Signature.bind_partial()
调用的结果。保存参数到函数的参数的映射。- arguments¶
参数名称到参数值的可变映射。仅包含显式绑定的参数。
arguments
中的更改将在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 参数为 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()
和 签名对象 提供了可调用内省的推荐 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)¶
计算对象的注释字典。
obj
可以是可调用对象、类或模块。传入任何其他类型的对象都会引发TypeError
。返回一个字典。
get_annotations()
每次调用都会返回一个新字典;对同一对象调用两次将返回两个不同但等效的字典。此函数为您处理一些细节
如果
eval_str
为真,则使用eval()
将类型为str
的值取消字符串化。这适用于字符串化注释(from __future__ import annotations
)。如果
obj
没有注释字典,则返回一个空字典。(函数和方法始终具有注释字典;类、模块和其他类型的可调用对象可能没有。)忽略类中的继承注释。如果类没有自己的注释字典,则返回一个空字典。
出于安全考虑,所有对对象成员和字典值的访问都使用
getattr()
和dict.get()
。始终、始终、始终返回一个新创建的字典。
eval_str
控制是否使用调用eval()
的结果替换类型为str
的值如果 eval_str 为真,则对类型为
str
的值调用eval()
。(请注意,get_annotations
不会捕获异常;如果eval()
引发异常,它将展开堆栈,超出get_annotations
调用。)如果 eval_str 为假(默认),则类型为
str
的值保持不变。
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
是访问任何对象的注释字典的最佳实践。有关注释最佳实践的更多信息,请参阅 注释最佳实践。在 3.10 版中添加。
解释器堆栈¶
以下某些函数返回 FrameInfo
对象。为了向后兼容,这些对象允许对 positions
之外的所有属性执行类似元组的操作。此行为被视为已弃用,未来可能会被移除。
- class inspect.FrameInfo¶
-
- filename¶
与记录对应的 frame 执行的代码关联的文件名。
- lineno¶
记录对应的 frame 执行的代码关联的当前行的行号。
- function¶
记录对应的 frame 正在执行的函数名。
- code_context¶
记录对应的 frame 正在执行的源代码的上下文行列表。
- index¶
正在
code_context
列表中执行的当前行索引。
- positions¶
dis.Positions
对象,其中包含记录对应的 frame 正在执行的指令关联的起始行号、结束行号、起始列偏移量和结束列偏移量。
3.11 版中已更改:
FrameInfo
现在是类实例(与之前的 命名元组 向后兼容)。
- class inspect.Traceback¶
- 文件名¶
与该回溯对应的帧所执行的代码关联的文件名。
- 行号¶
与该回溯对应的帧所执行的代码关联的当前行的行号。
- 函数¶
与该回溯对应的帧所执行的函数名。
- 代码上下文¶
与该回溯对应的帧所执行的源代码的上下文行列表。
- 索引¶
在
code_context
列表中正在执行的当前行的索引。
- 位置¶
dis.Positions
对象,其中包含与该回溯对应的帧所执行的指令关联的起始行号、结束行号、起始列偏移量和结束列偏移量。
3.11 版中已更改:
Traceback
现在是类实例(与之前的 命名元组 向后兼容)。
注意
保留对帧对象的引用(如在这些函数返回的第一帧记录中找到的)会导致程序创建引用循环。一旦创建了引用循环,则即使启用了 Python 的可选循环检测器,所有可以从形成循环的对象访问的对象的生命周期也会变得更长。如果必须创建此类循环,则务必确保显式中断它们,以避免延迟销毁对象和增加内存消耗。
虽然循环检测器会捕获这些循环,但可以通过在 finally
子句中移除循环来确定性地销毁帧(和局部变量)。如果在编译 Python 时禁用了循环检测器或使用了 gc.disable()
,这一点也很重要。例如
def handle_stackframe_without_leak():
frame = inspect.currentframe()
try:
# do something with the frame
finally:
del frame
如果您想保留帧(例如稍后打印回溯),您还可以使用 frame.clear()
方法中断引用循环。
大多数这些函数支持的可选 context 参数指定要返回的上下文行数,这些行数以当前行为中心。
- inspect.getframeinfo(frame, context=1)¶
获取有关框架或回溯对象的信息。返回
Traceback
对象。3.11 版中已更改:返回
Traceback
对象,而不是命名元组。
- inspect.getouterframes(frame, context=1)¶
获取框架及其所有外部框架的
FrameInfo
对象列表。这些框架表示导致创建 frame 的调用。返回列表中的第一个条目表示 frame;最后一个条目表示 frame 堆栈中的最外层调用。3.5 版中已更改:返回 命名元组
FrameInfo(frame, filename, lineno, function, code_context, index)
列表。3.11 版中已更改:返回
FrameInfo
对象列表。
- inspect.getinnerframes(traceback, context=1)¶
获取回溯框架及其所有内部框架的
FrameInfo
对象列表。这些框架表示因 frame 而进行的调用。列表中的第一个条目表示 traceback;最后一个条目表示引发异常的位置。3.5 版中已更改:返回 命名元组
FrameInfo(frame, filename, lineno, function, code_context, index)
列表。3.11 版中已更改:返回
FrameInfo
对象列表。
- inspect.currentframe()¶
返回调用者堆栈框架的框架对象。
CPython 实现细节:此函数依赖于解释器中的 Python 堆栈框架支持,在所有 Python 实现中都不保证存在。如果在没有 Python 堆栈框架支持的实现中运行,此函数将返回
None
。
静态获取属性¶
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)¶
获取异步生成器对象的当前状态。此函数旨在与
async def
函数创建的异步迭代器对象一起使用,这些函数使用yield
语句,但会接受任何具有ag_running
和ag_frame
属性的类似异步生成器对象。可能的状态有
AGEN_CREATED:等待开始执行。
AGEN_RUNNING:当前由解释器执行。
AGEN_SUSPENDED:当前在 yield 表达式处挂起。
AGEN_CLOSED:执行已完成。
在 3.12 版本中添加。
还可以查询生成器的当前内部状态。这主要用于测试目的,以确保内部状态按预期更新
- inspect.getgeneratorlocals(generator)¶
获取 generator 中活动局部变量到其当前值的映射。返回一个字典,其中映射从变量名到值。这等效于在生成器的主体中调用
locals()
,并且所有相同的警告都适用。如果生成器是没有任何关联帧的生成器,则返回一个空字典。如果生成器不是 Python 生成器对象,则引发
TypeError
。CPython 实现细节:此函数依赖于生成器公开 Python 堆栈帧以进行内省,这并不保证在所有 Python 实现中都是如此。在这种情况下,此函数将始终返回一个空字典。
在 3.3 版中添加。
- inspect.getcoroutinelocals(coroutine)¶
此函数类似于
getgeneratorlocals()
,但适用于由async def
函数创建的协程对象。在 3.5 版本中添加。
- inspect.getasyncgenlocals(agen)¶
此函数类似于
getgeneratorlocals()
,但适用于由async def
函数创建的异步生成器对象,该函数使用yield
语句。在 3.12 版本中添加。
代码对象位标志¶
Python 代码对象具有co_flags
属性,它是以下标志的位图
- inspect.CO_OPTIMIZED¶
代码对象已优化,使用快速局部变量。
- inspect.CO_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 版本中添加。
注意
这些标志特定于 CPython,可能未在其他 Python 实现中定义。此外,这些标志是实现细节,可以在将来的 Python 版本中删除或弃用。建议对任何内省需求使用inspect
模块中的公共 API。
缓冲区标志¶
命令行界面¶
inspect
模块还从命令行提供基本内省功能。
默认情况下,它接受模块名称并打印该模块的源代码。也可以通过附加冒号和目标对象的限定名称来打印模块内的类或函数。
- --details¶
打印指定对象的详细信息,而不是源代码