Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

การติดตามและบันทึกการทำงานของคำสั่ง Python (trace)

ฟังก์ชันในโมดูล 'trace' ของไลบรารี Python สร้างการติดตามการทำงานของโปรแกรม และการครอบคลุมคำสั่งที่มีคำอธิบายประกอบ ยังมีฟังก์ชันสำหรับแสดงรายการฟังก์ชันที่ถูกเรียกใช้ระหว่างรันโดยการสร้างความสัมพันธ์ของผู้เรียก (caller relationships)

ตัวอย่างต่อไปนี้ใช้สคริปต์ Python 2 ไฟล์ เพื่อสาธิตฟีเจอร์ของโมดูล 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 เพื่อข้ามไดเรกทอรีที่ระบุขณะสร้าง trace:

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(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()

ตัวเลือก --summary แสดงสรุปสั้นๆ หากใช้ร่วมกับตัวเลือก --count:

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 ระบุชื่อไฟล์ที่สะสมจำนวนนับจากการ trace หลายครั้ง:

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: 
filename: E:\python37\myfunctions.py, modulename: myfunctions, funcname: area
filename: E:\python37\myfunctions.py, modulename: myfunctions, funcname: factorial
filename: mymain.py, modulename: mymain, funcname: 
filename: mymain.py, modulename: mymain, funcname: main

ตัวเลือก --trackcalls ใช้ร่วมกับ --listfuncs สร้างความสัมพันธ์การเรียกใช้:

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.
*** E:\python37\myfunctions.py ***
myfunctions.factorial -> myfunctions.factorial
*** mymain.py ***
mymain. -> 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