28.13. 检查—检查活动对象

2.1 版中的新Function。

源代码: Lib/inspect.py


inspect模块提供了几个有用的Function,以帮助获取有关活动对象的信息,例如模块,类,方法,函数,回溯,框架对象和代码对象。例如,它可以帮助您检查类的内容,检索方法的源代码,提取函数的参数列表并设置其格式或获取显示详细回溯所需的所有信息。

该模块提供四种主要服务:类型检查,获取源代码,检查类和函数以及检查解释器堆栈。

28.13.1. 类型和成员

getmembers()函数检索对象的成员,例如类或模块。名称以“ is”开头的 16 个函数主要是为getmembers()的第二个参数提供方便的选择。它们还帮助您确定何时可以期望找到以下特殊属性:

TypeAttributeDescriptionNotes
moduledocdocumentation string
file文件名(内置模块缺失)
classdocdocumentation string
module定义此类的模块的名称
methoddocdocumentation string
name定义此方法的名称
im_class要求此方法的类对象(1)
im_func 或__func__函数对象,包含方法的实现
im_self 或__self__此方法绑定到的实例,或None
functiondocdocumentation string
name定义此Function的名称
func_code包含已编译函数bytecode的代码对象
func_defaults参数的任何默认值的 Tuples
func_doc(与__doc_相同)
func_globals定义此Function的全局名称空间
func_name(与__name_相同)
generatoriter定义为支持容器上的迭代
close在生成器内部引发新的 GeneratorExit 异常以终止迭代
gi_codecode object
gi_frame框架对象或 Generator 耗尽后可能为None
gi_running生成器执行时设置为 1,否则设置为 0
next从容器返回下一个项目
send恢复生成器并“发送”一个值,该值成为当前 yield-expression 的结果
throw用于在生成器内部引发异常
tracebacktb_frame在此级别上框架对象
tb_lasti字节码中最后try执行的指令的索引
tb_linenoPython 源代码中的当前行号
tb_next下一个内部回溯对象(由该级别调用)
framef_back下一个外部框架对象(此框架的调用者)
f_builtins此框架看到的内建名称空间
f_code在此框架中执行的代码对象
f_exc_traceback回溯(如果在此框架中引发),或None
f_exc_type异常类型(如果在此框架中引发),或None
f_exc_value异常值(如果在此框架中引发),或None
f_globals此框架看到的全局名称空间
f_lasti字节码中最后try执行的指令的索引
f_linenoPython 源代码中的当前行号
f_locals此框架看到的本地名称空间
f_restricted0 或 1(如果框架处于受限执行模式)
f_trace此框架或None的跟踪Function
codeco_argcount参数数量(不包括*或**参数)
co_code原始编译字节码的字符串
co_consts字节码中使用的常量 Tuples
co_filename在其中创建此代码对象的文件的名称
co_firstlinenoPython 源代码中第一行的数量
co_flags位图:1 =优化的| 2 = newlocals | 4 = * arg | 8 = ** arg
co_lnotab行号到字节码索引的编码 Map
co_name定义此代码对象的名称
co_names局部变量名称的 Tuples
co_nlocals局部变量数
co_stacksize所需的虚拟机堆栈空间
co_varnames参数和局部变量名称的 Tuples
builtindocdocumentation string
name该函数或方法的原始名称
self方法绑定到的实例,或None

Note:

  • 在版本 2.2 中更改:im_class用于引用定义该方法的类。

  • inspect. getmembers(* object * [,* predicate *])

    • 返回按名称排序的(名称,值)对列表中的对象的所有成员。如果提供了可选的* predicate *参数,则仅包含谓词为其返回真值的成员。

Note

当参数为类时,getmembers()不返回元类属性(此行为是从dir()函数继承的)。

  • inspect. getmoduleinfo(* path *)
    • 返回一个值的 Tuples,该值描述 Python 如何解释* path 标识的文件(如果是模块)或None(如果不标识为模块)。返回 Tuples 为(name, suffix, mode, module_type),其中 name 是模块名称,不包含任何封装包的名称, suffix 是文件名的结尾部分(可能不是点分隔的 extensions), mode 是将使用的open()模式('r''rb'),而 module_type *是提供模块类型的整数。 * module_type *将具有可以与imp模块中定义的常量进行比较的值;有关模块类型的更多信息,请参见该模块的文档。

在 2.6 版中更改:返回named tuple 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 函数(包括由lambda表达式创建的函数),则返回 true。
  • inspect. isgeneratorfunction(* object *)

    • 如果对象是 Python 生成器函数,则返回 true。

2.6 版的新Function。

  • inspect. isgenerator(* object *)
    • 如果对象是生成器,则返回 true。

2.6 版的新Function。

  • inspect. istraceback(* object *)

    • 如果对象是回溯,则返回 true。
  • inspect. isframe(* object *)

    • 如果对象是框架,则返回 true。
  • inspect. iscode(* object *)

    • 如果对象是代码,则返回 true。
  • inspect. isbuiltin(* object *)

    • 如果对象是内置函数或绑定的内置方法,则返回 true。
  • inspect. isroutine(* object *)

    • 如果对象是用户定义的或内置的函数或方法,则返回 true。
  • inspect. isabstract(* object *)

    • 如果对象是抽象 Base Class,则返回 true。

2.6 版的新Function。

这是从 Python 2.2 开始的新Function,例如int.__add__就是如此。pass此测试的对象具有get()方法,但没有set()方法,但除此之外,属性集有所不同。 name属性通常是明智的,而__doc__通常是明智的。

pass Descriptors 实现的方法也pass其他测试之一,则从ismethoddescriptor()测试返回 false,仅是因为其他测试承诺了更多–例如,当对象passismethod()时,您可以指望拥有im_func属性(等)。

  • inspect. isdatadescriptor(* object *)
    • 如果对象是数据 Descriptors,则返回 true。

数据 Descriptors 同时具有getset方法。示例包括属性(在 Python 中定义),getset 和成员。后两者是用 C 定义的,并且有针对这些类型的更具体的测试,这些测试在 Python 实现中非常可靠。通常,数据 Descriptors 还将具有name__doc__属性(属性,getset 和成员都具有这两个属性),但这不能保证。

2.3 版的新Function。

  • inspect. isgetsetdescriptor(* object *)
    • 如果对象是 getsetDescriptors,则返回 true。

CPython 实现细节: getset 是在扩展模块中passPyGetSetDef结构定义的属性。对于没有此类类型的 Python 实现,此方法将始终返回False

2.5 版的新Function。

  • inspect. ismemberdescriptor(* object *)
    • 如果对象是成员 Descriptors,则返回 true。

CPython 实现细节: 成员 Descriptors 是在扩展模块中passPyMemberDef结构定义的属性。对于没有此类类型的 Python 实现,此方法将始终返回False

2.5 版的新Function。

28.13.2. 检索源代码

  • inspect. getdoc(* object *)

    • 获取对象的文档字符串,用cleandoc()清理。
  • inspect. getcomments(* object *)

    • 以单个字符串返回紧接在对象源代码之前(对于类,函数或方法)或 Python 源文件顶部(如果对象是模块)的所有 Comments 行。
  • inspect. getfile(* object *)

    • 返回定义对象的(文本或二进制)文件的名称。如果对象是内置模块,类或函数,则失败并显示TypeError
  • inspect. getmodule(* object *)

    • try猜测在哪个模块中定义了对象。
  • inspect. getsourcefile(* object *)

    • 返回定义对象的 Python 源文件的名称。如果对象是内置模块,类或函数,则失败并显示TypeError
  • inspect. getsourcelines(* object *)

    • 返回对象的源代码行和起始行号的列表。参数可以是模块,类,方法,函数,回溯,框架或代码对象。返回源代码作为与对象相对应的行的列表,行号指示在原始源文件中找到第一行代码的位置。如果无法获取源代码,则会引发IOError
  • inspect. getsource(* object *)

    • 返回对象的源代码文本。参数可以是模块,类,方法,函数,回溯,框架或代码对象。源代码作为单个字符串返回。如果无法获取源代码,则会引发IOError
  • inspect. cleandoc(* doc *)

    • 从缩进以与代码块对齐的文档字符串中清除缩进。

从第一行删除所有前导空格。可以从第二行开始均匀删除的所有前导空格都将被删除。随后删除开头和结尾的空行。此外,所有选项卡都将扩展为空格。

2.6 版的新Function。

28.13.3. 类和Function

  • inspect. getclasstree(* classes * [,* unique *])

    • 将给定的类列表排列为嵌套列表的层次结构。在出现嵌套列表的地方,它包含派生自该类的类,这些类的条目紧接在列表之前。每个条目都是一个 2Tuples,其中包含一个类及其 Base Class 的 Tuples。如果* unique *参数为 true,则对于给定列表中的每个类,仅在返回的结构中出现一个条目。否则,使用多重继承的类及其子代将出现多次。
  • inspect. getargspec(* func *)

    • 获取 Python 函数参数的名称和默认值。返回包含四个内容的 Tuples:(args, varargs, keywords, defaults)。 * args *是参数名称的列表(它可能包含嵌套列表)。 * varargs keywords *是***参数或None的名称。 * defaults 是默认参数值的 Tuples;如果没有默认参数,则为None;如果该 Tuples 具有 n 个元素,则它们对应于 args 中列出的最后 n *个元素。

在 2.6 版中更改:返回named tuple ArgSpec(args, varargs, keywords, defaults)

  • inspect. getargvalues(* frame *)
    • 获取有关传递到特定框架的参数的信息。返回包含四个内容的 Tuples:(args, varargs, keywords, locals)。 * args *是参数名称的列表(它可能包含嵌套列表)。 * varargs keywords *是***参数或None的名称。 * locals *是给定框架的本地字典。

在 2.6 版中更改:返回named tuple ArgInfo(args, varargs, keywords, locals)

  • inspect. formatargspec(* args * [,* varargs varkw defaults formatarg formatvarargs formatvarkw formatvalue join *])

    • 根据getargspec()返回的四个值格式化漂亮的参数 spec。 format *参数是相应的可选格式化函数,这些函数被调用以将名称和值转换为字符串。
  • inspect. formatargvalues(* args * [,* varargs varkw locals formatarg formatvarargs formatvarkw formatvalue join *])

    • 根据getargvalues()返回的四个值格式化漂亮的参数 spec。 format *参数是相应的可选格式化函数,这些函数被调用以将名称和值转换为字符串。
  • inspect. getmro(* cls *)

    • 以方法解析 Sequences 返回类 cls 的 Base Class(包括 cls)的 Tuples。在该 Tuples 中,没有一个类出现多次。请注意,方法的解析 Sequences 取决于 cls 的类型。除非使用非常特殊的用户定义的元类型,否则 cls 将是 Tuples 的第一个元素。
  • inspect. getcallargs(* func [,* args] [,** kwds] *)

    • 将* args kwds 绑定到 Python 函数或方法 func 的参数名称,就好像它们是由它们调用的一样。对于绑定方法,还将第一个参数(通常命名为self)绑定到关联的实例。返回一个字典,将参数名称(包括***参数的名称,如果有的话)Map 到 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,)}
>>> 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 版的新Function。

28.13.4. 解释器堆栈

当以下函数返回“框架记录”时,每个记录都是六个项的 Tuples:框架对象,文件名,当前行的行号,函数名称,源代码中的上下文行列表,以及该列表中当前行的索引。

Note

在框架的第一个元素中记录到这些函数返回的内容时,保留对框架对象的引用可能会导致程序创建引用循环。创建参考循环后,即使启用了 Python 的可选循环检测器,也可以从构成循环的对象访问的所有对象的寿命变得更长。如果必须创建这样的循环,则重要的是要确保将其明确断开,以避免延迟破坏对象和增加内存消耗。

尽管循环检测器将捕获这些错误,但是可以pass删除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 *])
    • 获取有关框架或回溯对象的信息。返回一个 5Tuples,该帧的帧记录的最后五个元素。

在 2.6 版中更改:返回named tuple Traceback(filename, lineno, function, code_context, index)

  • inspect. getouterframes(* frame * [,* context *])

    • 获取一个框架和所有外部框架的框架记录列表。这些框架表示导致创建* frame 的调用。返回列表中的第一项表示 frame ;最后一个条目表示 frame *堆栈上的最外层调用。
  • inspect. getinnerframes(* traceback * [,* context *])

    • 获取回溯帧和所有内部帧的帧记录列表。这些框架表示由于* frame 而进行的调用。列表中的第一项表示 traceback *;最后一个条目表示引发异常的位置。
  • inspect. currentframe ( )

    • 返回调用者的堆栈框架的框架对象。

CPython 实现细节: 此函数依赖于解释器中的 Python 堆栈框架支持,并不能保证在所有 Python 实现中都存在。如果在没有 Python 堆栈框架支持的实现中运行,则此函数返回None

  • inspect. stack([* context *])

    • 返回调用者堆栈的帧记录列表。返回列表中的第一项代表呼叫者;最后一个条目表示堆栈上的最外层调用。
  • inspect. trace([* context *])

    • 返回当前帧与其中引发了当前正在处理的异常的帧之间的堆栈的帧记录的列表。最后一个条目表示引发异常的位置。