追蹤或跟蹤 Python 語句執行(跟蹤)


Python 庫中 'trace' 模組中的函式生成程式執行的跟蹤,以及帶註釋的語句覆蓋率。它還具有透過生成呼叫者關係來列出執行期間呼叫的函式的功能。

以下兩個 Python 指令碼用作示例來演示 trace 模組的功能。

#myfunctions.py
import math
def area(x):
   a = math.pi*math.pow(x,2)
   return a
def factorial(x):
   if x==1:
      return 1
   else:
return x*factorial(x-1)
#mymain.py
import myfunctions
def main():
   x = 5
   print ('area=',myfunctions.area(x))
   print ('factorial=',myfunctions.factorial(x))

if __name__=='__main__':
   main()

'trace' 模組具有命令列介面。模組中的所有函式都可以使用命令列開關呼叫。最重要的選項是 **--trace**,它在執行時顯示程式行。在以下示例中,使用了另一個選項 **--ignore-dir**。它在生成跟蹤時忽略指定的目錄。

E:\python37>python -m trace --ignore-dir=../lib --trace mymain.py

輸出

mymain.py(2): def main():
mymain.py(7): if __name__=='__main__':
mymain.py(8): main()
--- modulename: mymain, funcname: main
mymain.py(3): x=5
mymain.py(4): print ('area=',myfunctions.area(x))
--- modulename: myfunctions, funcname: area
myfunctions.py(3): a=math.pi*math.pow(x,2)
myfunctions.py(4): return a
area= 78.53981633974483
mymain.py(5): print ('factorial=',myfunctions.factorial(x))
--- modulename: myfunctions, funcname: factorial
myfunctions.py(6): if x==1:
myfunctions.py(9): return x*factorial(x-1)
--- modulename: myfunctions, funcname: factorial
myfunctions.py(6): if x==1:
myfunctions.py(9): return x*factorial(x-1)
--- modulename: myfunctions, funcname: factorial
myfunctions.py(6): if x==1:
myfunctions.py(9): return x*factorial(x-1)
--- modulename: myfunctions, funcname: factorial
myfunctions.py(6): if x==1:
myfunctions.py(9): return x*factorial(x-1)
--- modulename: myfunctions, funcname: factorial
myfunctions.py(6): if x==1:
myfunctions.py(7): return 1
factorial= 120

**--count** 選項為每個正在使用的模組生成一個檔案,副檔名為 cover。

E:\python37>python -m trace --count mymain.py
area= 78.53981633974483
factorial = 120

myfunctions.cover

1: import math
1: def area(x):
1:    a = math.pi*math.pow(x,2)
1:    return a
1: def factorial(x):
5:    if x==1:
1:       return 1
   else:
4:    return x*factorial(x-1)

mymain.cover

1: import myfunctions
1: def main():
1:    x = 5
1:    print ('area=',myfunctions.area(x))
1:    print ('factorial=',myfunctions.factorial(x))

1: if __name__=='__main__':
1:    main()

如果還使用了 –count 選項,則 **--summary** 選項會顯示簡要摘要。

E:\python37>python -m trace --count --summary mymain.py
area = 78.53981633974483
factorial = 120
lines cov% module (path)
   8 100% myfunctions (E:\python37\myfunctions.py)
   7 100% mymain (mymain.py)

**--file** 選項指定累積多次跟蹤執行計數的檔案的名稱。

E:\python37>python -m trace --count --file report.txt mymain.py
area = 78.53981633974483
factorial = 120
Skipping counts file 'report.txt': [Errno 2] No such file or directory: 'report.txt'

E:\python37>python -m trace --count --file report.txt mymain.py
area= 78.53981633974483
factorial= 120

**--listfuncs** 選項顯示程式執行期間呼叫的函式。

E:\python37>python -m trace --listfunc mymain.py | findstr -v importlib
area= 78.53981633974483
factorial= 120

functions called:
filename: E:\python37\lib\encodings\cp1252.py, modulename: cp1252, funcname: IncrementalEncoder.encode
filename: E:\python37\myfunctions.py, modulename: myfunctions, funcname: <module>
filename: E:\python37\myfunctions.py, modulename: myfunctions, funcname: area
filename: E:\python37\myfunctions.py, modulename: myfunctions, funcname: factorial
filename: mymain.py, modulename: mymain, funcname: <module>
filename: mymain.py, modulename: mymain, funcname: main

**--trackcalls** 選項與 –list funcs 選項一起使用。它生成呼叫關係。

E:\python37>python -m trace --listfunc --trackcalls mymain.py | findstr -v importlib
area= 78.53981633974483
factorial= 120

calling relationships:

--> E:\python37\myfunctions.py


*** E:\python37\lib\trace.py ***
--> mymain.py
trace.Trace.runctx -> mymain.<module>

*** E:\python37\myfunctions.py ***
myfunctions.factorial -> myfunctions.factorial

*** mymain.py ***
mymain.<module> -> mymain.main
--> E:\python37\lib\encodings\cp1252.py
mymain.main -> cp1252.IncrementalEncoder.encode
--> E:\python37\myfunctions.py
mymain.main -> myfunctions.area
mymain.main -> myfunctions.factorial

更新於: 2019-07-30

5K+ 瀏覽量

啟動你的 職業生涯

透過完成課程獲得認證

開始
廣告