# `trace` --- 追蹤或追查 Python 陳述式執行

原始碼：Lib/trace.py

`trace` 模組可用來追蹤程式執行過程、產生帶註解的陳述式涵蓋範圍清單、輸出呼叫者／被呼叫者的關係，以及在程式執行期間被執行的函式串列。它可以在其他程式中使用，也可以從命令列啟動。

也參考

Coverage.py

  一款受歡迎的第三方涵蓋範圍工具，提供 HTML 輸出與分支涵蓋等進階功能。

## 命令列用法

`trace` 模組可從命令列執行，用法可以非常簡單，如：:

    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

  顯示程式執行時產生的呼叫關係。

### 修飾子（Modifier）

-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

  在每一行前加上自程式啟動以來的經過時間。僅在追蹤時使用。

### 篩選子（Filter）

這些選項可以重複使用多次。

--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 必須是可傳入 `exec()` 的字串或程式碼物件。

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

    在指定的全域與區域命名空間中，根據目前的追蹤參數執行命令並收集統計資料。若未指定，globals 與 locals 預設為空字典。

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

    在目前的追蹤參數下，使用 `Trace` 物件控制呼叫 func，並傳入指定的引數。

  results()

    回傳一個 `CoverageResults` 物件，包含指定 `Trace` 實例中所有先前對 `run`、`runctx` 與 `runfunc` 呼叫的累積結果。不會重設累積的追蹤結果。

class trace.CoverageResults

  一個用來儲存涵蓋範圍結果的容器，由 `Trace.results()` 建立。不應由使用者直接建立。

  update(other)

    合併來自另一個 `CoverageResults` 物件的資料。

  write_results(show_missing=True, summary=False, coverdir=None, *, ignore_missing_files=False)

    寫入涵蓋範圍結果。將 show_missing 設為真可顯示未被執行的程式碼行；將 summary 設為真則會在輸出中加入每個模組的涵蓋範圍摘要。coverdir 指定輸出涵蓋範圍結果檔案的目錄，若為 `None`，則每個原始檔案的結果會輸出至其所在目錄中。

    若 ignore_missing_files 為 `True`，則會忽略那些已不存在的檔案的涵蓋範圍資料，不會顯示任何錯誤。否則，缺少的檔案將會引發 `FileNotFoundError`。

    在 3.13 版的變更: 新增 ignore_missing_files 參數。

以下是一個簡單範例，展示如何使用程式介面：

    import sys
    import trace

    # 建立一個 Trace 物件，指定要忽略的目錄，
    # 並設定是否進行追蹤、行數統計或兩者皆做。
    tracer = trace.Trace(
        ignoredirs=[sys.prefix, sys.exec_prefix],
        trace=0,
        count=1)

    # 使用該 tracer 執行新的命令
    tracer.run('main()')

    # 建立報告，將輸出放在目前目錄中
    r = tracer.results()
    r.write_results(show_missing=True, coverdir=".")