trace —— 跟踪 Python 语句的执行

源代码Lib/trace.py


模块 trace 模块用于跟踪程序的执行过程,可生成带注释的语句覆盖率列表,打印调用/被调用关系,列出程序运行期间执行过的函数。该模块可在其他程序或命令行中使用。

参见

Coverage.py

流行的第三方代码覆盖工具,可输出 HTML ,并提供分支覆盖等高级功能。

命令行用法

trace 模块可由命令行调用。用法如此简单:

  1. python -m trace --count -C . somefile.py ...

上述命令将执行 somefile.py ,并在当前目录生成执行期间所有已导入 Python 模块的带注解列表。

--help

显示用法并退出。

--version

显示模块版本并退出。

3.8 新版功能: 加入了 --module 选项,允许运行可执行模块。

主要的可选参数

在调用 trace 时,至少须指定以下可选参数之一。 -listfuncs-trace-count 相互排斥。如果给出 --listfuncs,就再不会接受 --count--trace ,反之亦然。

-c, —count

在程序完成时生成一组带有注解的报表文件,显示每个语句被执行的次数。 参见下面的 -coverdir-file-no-report

-t, —trace

执行时显示每一行。

-l, —listfuncs

显示程序运行时执行到的函数。

-r, —report

由之前用了 --count--file 运行的程序产生一个带有注解的报表。 不会执行代码。

-T, —trackcalls

显示程序运行时暴露出来的调用关系。

修饰器

-f, —file=<file>

用于累计多次跟踪运行计数的文件名。应与 --count 一起使用。

-C, —coverdir=<dir>

报表文件的所在目录。package.module 的覆盖率报表将被写入文件 _dir_/_package_/_module_.cover

-m, —missing

生成带注解的报表时,用 >>>>>> 标记未执行的行。

-s, —summary

在用到 --count--report 时,将每个文件的简短摘要输出到 stdout。

-R, —no-report

不生成带注解的报表。如果打算用 --count 执行多次运行,然后在最后产生一组带注解的报表,该选项就很有用。

-g, —timing

在每一行前面加上时间,自程序运行算起。只在跟踪时有用。

过滤器

以下参数可重复多次。

--ignore-module=<mod>

忽略给出的模块名及其子模块(若为包)。参数可为逗号分隔的名称列表。

--ignore-dir=<dir>

忽略指定目录及其子目录下的所有模块和包。参数可为 os.pathsep 分隔的目录列表。

编程接口

class trace.Trace(count=1, trace=1, countfuncs=0, countcallers=0, ignoremods=(), ignoredirs=(), infile=None, outfile=None, timing=False)

创建一个对象来跟踪单个语句或表达式的执行。所有参数均为选填。 count 可对行号计数。 trace 启用单行执行跟踪。 countfuncs 可列出运行过程中调用的函数。 countcallers 可跟踪调用关系。 ignoremods 是要忽略的模块或包的列表。ignoredirs 是要忽略的模块或包的目录列表。 infile 是个文件名,从该文件中读取存储的计数信息。 outfile 是用来写入最新计数信息的文件名。 timing 可以显示相对于跟踪开始时间的时间戳。

  • run(cmd)

    执行命令,并根据当前跟踪参数从执行过程中收集统计数据。 cmd 必须为字符串或 code 对象,可供传入 exec()

  • runctx(cmd, globals=None, locals=None)

    在定义的全局和局部环境中,执行命令并收集当前跟踪参数下的执行统计数据。若没有定义 globalslocals ,则默认为空字典。

  • runfunc(func, /, *args, **kwds)

    Trace 对象的控制下,用给定的参数调用 func,并采用当前的跟踪参数。

  • results()

    返回一个 CoverageResults 对象,包含之前对指定 Trace 实例调用 runrunctxrunfunc 的累积结果。 累积的跟踪结果不会重置。

class trace.CoverageResults

存放代码覆盖结果的容器,由 Trace.results() 创建。用户不应直接去创建。

  • update(other)

    从另一个 CoverageResults 对象中合并代码覆盖数据。

  • write_results(show_missing=True, summary=False, coverdir=None)

    写入代码覆盖结果。设置 show_missing 可显示未命中的行。设置*summary* 可在输出中包含每个模块的覆盖率摘要信息。 coverdir 可指定覆盖率结果文件的输出目录,为 None 则结果将置于源文件所在目录中。

以下例子简单演示了编程接口的用法:

  1. import sys
  2. import trace
  3. # create a Trace object, telling it what to ignore, and whether to
  4. # do tracing or line-counting or both.
  5. tracer = trace.Trace(
  6. ignoredirs=[sys.prefix, sys.exec_prefix],
  7. trace=0,
  8. count=1)
  9. # run the new command using the given tracer
  10. tracer.run('main()')
  11. # make a report, placing output in the current directory
  12. r = tracer.results()
  13. r.write_results(show_missing=True, coverdir=".")