28.13. 检查 — 检查活动对象 — Python 文档
28.13. 检查 — 检查活动对象
2.1 版中的新功能。
inspect 模块提供了几个有用的函数来帮助获取有关活动对象的信息,例如模块、类、方法、函数、回溯、框架对象和代码对象。 例如,它可以帮助您检查类的内容、检索方法的源代码、提取和格式化函数的参数列表,或者获取显示详细回溯所需的所有信息。
该模块提供四种主要服务:类型检查、获取源代码、检查类和函数以及检查解释器堆栈。
28.13.1. 类型和成员
getmembers() 函数检索对象的成员,例如类或模块。 名称以“is”开头的 16 个函数主要用作 getmembers() 的第二个参数的方便选择。 它们还可以帮助您确定何时可以找到以下特殊属性:
类型 | 属性 | 描述 | 笔记 |
---|---|---|---|
模块 | __文档__ | 文档字符串 | |
__文件__ | 文件名(缺少内置模块) | ||
班级 | __文档__ | 文档字符串 | |
__模块__ | 定义此类的模块的名称 | ||
方法 | __文档__ | 文档字符串 | |
__名称__ | 定义此方法的名称 | ||
im_class | 要求此方法的类对象 | (1) | |
im_func 或 __func__ | 包含方法实现的函数对象 | ||
im_self 或 __self__ | 此方法绑定到的实例,或 None
|
||
功能 | __文档__ | 文档字符串 | |
__名称__ | 定义此函数的名称 | ||
函数代码 | 包含编译函数的代码对象 bytecode | ||
func_defaults | 参数的任何默认值的元组 | ||
func_doc | (与 __doc__ 相同) | ||
func_globals | 定义此函数的全局命名空间 | ||
功能名称 | (与 __name__ 相同) | ||
发电机 | __iter__ | 定义为支持容器迭代 | |
关 | 在生成器内引发新的 GeneratorExit 异常以终止迭代 | ||
gi_code | 代码对象 | ||
gi_frame | 一旦生成器耗尽,框架对象或可能 None
|
||
gi_running | 生成器执行时设置为 1,否则设置为 0 | ||
下一个 | 从容器中返回下一个项目 | ||
发送 | 恢复生成器并“发送”一个值,该值成为当前产量表达式的结果 | ||
扔 | 用于在生成器内部引发异常 | ||
追溯 | tb_frame | 此级别的框架对象 | |
tb_lasti | 字节码中最后尝试指令的索引 | ||
tb_lineno | Python 源代码中的当前行号 | ||
tb_next | 下一个内部回溯对象(由该级别调用) | ||
框架 | f_back | 下一个外部框架对象(此框架的调用者) | |
f_builtins | 这个框架看到的内置命名空间 | ||
代码 | 在此帧中执行的代码对象 | ||
f_exc_traceback | 如果在此框架中引发回溯,或 None
|
||
f_exc_type | 如果在此帧中引发异常类型,或 None
|
||
f_exc_value | 如果在此帧中引发异常值,或 None
|
||
f_globals | 这个框架看到的全局命名空间 | ||
f_lasti | 字节码中最后尝试指令的索引 | ||
f_lineno | Python 源代码中的当前行号 | ||
f_locals | 此框架看到的本地命名空间 | ||
f_restricted | 如果帧处于受限执行模式,则为 0 或 1 | ||
f_trace | 此帧的跟踪功能,或 None
|
||
代码 | co_argcount | 参数的数量(不包括 * 或 ** args) | |
代码 | 原始编译字节码字符串 | ||
co_consts | 字节码中使用的常量元组 | ||
文件名 | 在其中创建此代码对象的文件的名称 | ||
co_firstlineno | Python 源代码中第一行的数量 | ||
co_flags | 2=newlocals | 4=*arg | 8=**arg
|
||
co_lnotab | 行号到字节码索引的编码映射 | ||
co_name | 定义此代码对象的名称 | ||
co_names | 局部变量名称元组 | ||
co_nlocals | 局部变量的数量 | ||
co_stacksize | 需要的虚拟机堆栈空间 | ||
co_varnames | 参数名称和局部变量的元组 | ||
内置 | __文档__ | 文档字符串 | |
__名称__ | 此函数或方法的原始名称 | ||
__自己__ | 方法绑定到的实例,或 None
|
笔记:
2.2 版更改:
im_class
用于引用定义方法的类。
- inspect.getmembers(object[, predicate])
在按名称排序的 (name, value) 对列表中返回对象的所有成员。 如果提供了可选的 predicate 参数,则仅包括谓词为其返回真值的成员。
笔记
getmembers() 在参数是类时不返回元类属性(此行为继承自 dir() 函数)。
- inspect.getmoduleinfo(path)
返回一个值元组,描述 Python 如何解释由 path 标识的文件,如果它是一个模块,或者
None
如果它不会被标识为一个模块。 返回元组是(name, suffix, mode, module_type)
,其中 name 是模块的名称,没有任何封闭包的名称,suffix 是文件名的结尾部分(其中可能不是点分隔的扩展名),mode 是将使用的 open() 模式('r'
或'rb'
),和module_type 是一个整数,给出了模块的类型。 module_type 将有一个值,可以与 imp 模块中定义的常量进行比较; 有关模块类型的更多信息,请参阅该模块的文档。在 2.6 版更改: 返回一个名为 的元组
ModuleInfo(name, suffix, mode, module_type)
。
- inspect.getmodulename(path)
- 返回由文件 path 命名的模块的名称,不包括封闭包的名称。 这与解释器在搜索模块时使用的算法相同。 如果根据解释器的规则无法匹配名称,则返回
None
。
- inspect.ismodule(object)
- 如果对象是模块,则返回 true。
- inspect.isclass(object)
- 如果对象是一个类,无论是内置的还是在 Python 代码中创建的,则返回 true。
- inspect.ismethod(object)
- 如果对象是用 Python 编写的绑定或未绑定方法,则返回 true。
- inspect.isfunction(object)
- 如果对象是 Python 函数,则返回 true,其中包括由 lambda 表达式创建的函数。
- inspect.isgeneratorfunction(object)
如果对象是 Python 生成器函数,则返回 true。
2.6 版中的新功能。
- inspect.isgenerator(object)
如果对象是生成器,则返回 true。
2.6 版中的新功能。
- inspect.istraceback(object)
- 如果对象是回溯,则返回 true。
- inspect.isframe(object)
- 如果对象是框架,则返回 true。
- inspect.iscode(object)
- 如果对象是代码,则返回 true。
- inspect.isbuiltin(object)
- 如果对象是内置函数或绑定的内置方法,则返回 true。
- inspect.isroutine(object)
- 如果对象是用户定义的或内置的函数或方法,则返回 true。
- inspect.isabstract(object)
如果对象是抽象基类,则返回 true。
2.6 版中的新功能。
- inspect.ismethoddescriptor(object)
如果对象是方法描述符,则返回 true,但如果 ismmethod()、isclass()、isfunction() 或 isbuiltin()[ X142X] 是真的。
这是 Python 2.2 的新功能,例如,
int.__add__
也是如此。 通过此测试的对象具有 __get__() 方法,但没有 __set__() 方法,但除此之外,属性集各不相同。 __name__ 属性通常是明智的,而__doc__
通常是明智的。通过也通过其他测试之一的描述符实现的方法从 ismmethoddescriptor() 测试返回 false,仅仅因为其他测试承诺更多 – 例如,您可以指望拥有
im_func
当对象通过 方法() 时的属性(等)。
- inspect.isdatadescriptor(object)
如果对象是数据描述符,则返回 true。
数据描述符同时具有 __get__ 和 __set__ 方法。 示例是属性(在 Python 中定义)、getset 和成员。 后两者是在 C 中定义的,并且这些类型有更具体的测试可用,这在 Python 实现中是健壮的。 通常,数据描述符还将具有 __name__ 和
__doc__
属性(属性、getset 和成员具有这两个属性),但这并不能保证。2.3 版中的新功能。
- inspect.isgetsetdescriptor(object)
如果对象是 getset 描述符,则返回 true。
2.5 版中的新功能。
- inspect.ismemberdescriptor(object)
如果对象是成员描述符,则返回 true。
2.5 版中的新功能。
28.13.2. 检索源代码
- inspect.getdoc(object)
- 获取对象的文档字符串,用 cleandoc() 清理。
- inspect.getcomments(object)
- 在单个字符串中返回紧接在对象源代码之前(对于类、函数或方法)或 Python 源文件顶部(如果对象是模块)的任何注释行。
- inspect.getfile(object)
- 返回定义对象的(文本或二进制)文件的名称。 如果对象是内置模块、类或函数,这将失败并显示
TypeError
。
- inspect.getmodule(object)
- 尝试猜测对象是在哪个模块中定义的。
- inspect.getsourcefile(object)
- 返回定义对象的 Python 源文件的名称。 如果对象是内置模块、类或函数,这将失败并显示
TypeError
。
- inspect.getsourcelines(object)
- 返回对象的源行列表和起始行号。 参数可以是模块、类、方法、函数、回溯、框架或代码对象。 源代码作为与对象对应的行列表返回,行号指示在原始源文件中找到第一行代码的位置。 如果无法检索源代码,则会引发
IOError
。
- inspect.getsource(object)
- 返回对象的源代码文本。 参数可以是模块、类、方法、函数、回溯、框架或代码对象。 源代码作为单个字符串返回。 如果无法检索源代码,则会引发
IOError
。
- inspect.cleandoc(doc)
清除缩进以与代码块对齐的文档字符串中的缩进。
从第一行中删除所有前导空格。 任何可以从第二行开始统一删除的前导空格都将被删除。 随后删除开头和结尾的空行。 此外,所有选项卡都扩展为空格。
2.6 版中的新功能。
28.13.3. 类和函数
- inspect.getclasstree(classes[, unique])
- 将给定的类列表排列成嵌套列表的层次结构。 在嵌套列表出现的地方,它包含从其条目紧接在列表之前的类派生的类。 每个条目都是一个 2 元组,包含一个类和一个其基类的元组。 如果 unique 参数为真,则给定列表中每个类的返回结构中只出现一个条目。 否则,使用多重继承的类及其后代将出现多次。
- inspect.getargspec(func)
获取 Python 函数参数的名称和默认值。 返回四项元组:
(args, varargs, keywords, defaults)
。 args 是参数名称的列表(它可能包含嵌套列表)。 varargs 和 keywords 是*
和**
参数或None
的名称。 defaults 是默认参数值的元组,如果没有默认参数,则为None
; 如果此元组具有 n 元素,则它们对应于 args 中列出的最后一个 n 元素。在 2.6 版更改: 返回一个名为 的元组
ArgSpec(args, varargs, keywords, defaults)
。
- inspect.getargvalues(frame)
获取有关传递到特定框架的参数的信息。 返回四项元组:
(args, varargs, keywords, locals)
。 args 是参数名称的列表(它可能包含嵌套列表)。 varargs 和 keywords 是*
和**
参数或None
的名称。 locals 是给定帧的局部字典。在 2.6 版更改: 返回一个名为 的元组
ArgInfo(args, varargs, keywords, locals)
。
- inspect.formatargspec(args[, varargs, varkw, defaults, formatarg, formatvarargs, formatvarkw, formatvalue, join])
- 根据 getargspec() 返回的四个值格式化一个漂亮的参数规范。 format* 参数是相应的可选格式化函数,它们被调用以将名称和值转换为字符串。
- inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue, join])
- 根据 getargvalues() 返回的四个值格式化一个漂亮的参数规范。 format* 参数是相应的可选格式化函数,它们被调用以将名称和值转换为字符串。
- inspect.getmro(cls)
- 按方法解析顺序返回类 cls 的基类的元组,包括 cls。 在这个元组中没有类出现不止一次。 请注意,方法解析顺序取决于 cls 的类型。 除非使用非常特殊的用户定义元类型,否则 cls 将是元组的第一个元素。
- inspect.getcallargs(func[, *args][, **kwds])
将 args 和 kwds 绑定到 Python 函数或方法 func 的参数名称,就好像它被它们一起调用一样。 对于绑定方法,还将第一个参数(通常命名为
self
)绑定到关联的实例。 返回一个字典,将参数名称(包括*
和**
参数的名称,如果有的话)映射到 args 和 kwds[ X165X]。 在错误地调用 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,)} >>> getcallargs(f, a=2, x=4) {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()} >>> getcallargs(f) Traceback (most recent call last): ... TypeError: f() takes at least 1 argument (0 given)
2.7 版中的新功能。
28.13.4. 解释器栈
当以下函数返回“帧记录”时,每条记录都是一个包含 6 项的元组:帧对象、文件名、当前行的行号、函数名、源代码中的上下文行列表以及该列表中当前行的索引。
笔记
保持对帧对象的引用(如在帧记录这些函数返回的第一个元素中找到)可能会导致您的程序创建引用循环。 一旦创建了引用循环,即使启用了 Python 的可选循环检测器,可以从形成循环的对象访问的所有对象的生命周期也会变得更长。 如果必须创建这样的循环,重要的是确保它们被明确破坏以避免对象的延迟破坏和内存消耗增加。
尽管循环检测器会捕捉到这些,但可以通过删除 finally 子句中的循环来确定帧(和局部变量)的破坏。 如果在编译 Python 或使用 gc.disable() 时禁用循环检测器,这也很重要。 例如:
def handle_stackframe_without_leak():
frame = inspect.currentframe()
try:
# do something with the frame
finally:
del frame
大多数这些函数支持的可选 context 参数指定要返回的上下文行数,这些行以当前行为中心。
- inspect.getframeinfo(frame[, context])
获取有关框架或回溯对象的信息。 返回一个 5 元组,即帧的帧记录的最后五个元素。
在 2.6 版更改: 返回一个名为 的元组
Traceback(filename, lineno, function, code_context, index)
。
- inspect.getouterframes(frame[, context])
- 获取一个框架和所有外部框架的框架记录列表。 这些帧代表导致创建帧的调用。 返回列表中的第一个条目代表 frame; 最后一个条目代表 frame 堆栈上的最外层调用。
- inspect.getinnerframes(traceback[, context])
- 获取回溯帧和所有内部帧的帧记录列表。 这些帧表示由 帧 引起的调用。 列表中的第一个条目代表 traceback; 最后一个条目表示引发异常的位置。
- inspect.currentframe()
- 返回调用者堆栈帧的帧对象。
- inspect.stack([context])
- 返回调用者堆栈的帧记录列表。 返回列表中的第一个条目代表调用者; 最后一个条目代表堆栈上最外层的调用。
- inspect.trace([context])
- 返回当前帧和引发当前正在处理的异常的帧之间堆栈的帧记录列表。 列表中的第一个条目代表调用者; 最后一个条目表示引发异常的位置。