歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Python調試方法及性能調試

Python調試方法及性能調試

日期:2017/3/1 11:02:01   编辑:Linux編程
python pdb調試

python -m pdb myscript.py #注意這會重啟myscript.py

可以在程序中這麼設置斷點:
import pdb; pdb.set_trace()

可以修改變量的值,但是要注意,前面加上!比如要修改final的值,應該這樣!final="newvalue"

支持的命令:
p 打印變量
n next
step 細點運行
c continue
l list
a args 打印當前函數的參數
condition bpnumber [condition]
clear/disable/enable 清除/禁用/使能斷點
q quit


python profiler性能分析
一種方法: if __name__ == "__main__": import profile profile.run("foo()")
另一種命令行方法:python -m profile prof1.py profile的統計結果分為ncalls, tottime, percall, cumtime, percall, filename:lineno(function)等若干列: ncalls 函數的被調用次數 tottime 函數總計運行時間,除去函數中調用的函數運行時間 percall 函數運行一次的平均時間,等於tottime/ncalls cumtime 函數總計運行時間,含調用的函數運行時間 percall 函數運行一次的平均時間,等於cumtime/ncalls filename:lineno(function) 函數所在的文件名,函數的行號,函數名 用pstats自定義報表 profile解 決了我們的一個需求,還有一個需求:以多種形式查看輸出,我們可以通過 profile的另一個類Stats來解決。在這裡我們需要引入一個模塊pstats,它定義了一個類Stats,Stats的構造函數接受一個參數—— 就是profile的輸出文件的文件名。Stats提供了對profile輸出結果進行排序、輸出控制等功能,如我們把前文的程序改為如下: # …略 if __name__ == "__main__": import profile profile.run("foo()", "prof.txt") import pstats p = pstats.Stats("prof.txt") p.sort_stats("time").print_stats() 引入pstats之後,將profile的輸出按函數占用的時間排序 Stats有若干個函數,這些函數組合能給我們輸出不同的profile報表,功能非常強大。下面簡單地介紹一下這些函數: strip_dirs() 用以除去文件名前名的路徑信息。 add(filename,[…]) 把profile的輸出文件加入Stats實例中統計 dump_stats(filename) 把Stats的統計結果保存到文件 sort_stats(key,[…]) 最重要的一個函數,用以排序profile的輸出 reverse_order() 把Stats實例裡的數據反序重排 print_stats([restriction,…]) 把Stats報表輸出到stdout print_callers([restriction,…]) 輸出調用了指定的函數的函數的相關信息 print_callees([restriction,…]) 輸出指定的函數調用過的函數的相關信息 這裡最重要的函數就是sort_stats和print_stats,通過這兩個函數我們幾乎可以用適當的形式浏覽所有的信息了,下面來詳細介紹一下。 sort_stats() 接受一個或者多個字符串參數,如”time”、”name” 等,表明要根據哪一列來排序,這相當有用,例如我們可以通過用time為key來排序得知最消耗時間的函數,也可以通過cumtime來排序,獲知總消耗 時間最多的函數,這樣我們優化的時候就有了針對性,也就事半功倍了。sort_stats可接受的參數如下: ‘ncalls’ 被調用次數 ‘cumulative’ 函數運行的總時間 ‘file’ 文件名 ‘module’ 文件名 ‘pcalls’ 簡單調用統計(兼容舊版,未統計遞歸調用) ‘line’ 行號 ‘name’ 函數名 ‘nfl’ Name/file/line ‘stdname’ 標准函數名 ‘time’ 函數內部運行時間(不計調用子函數的時間) 另一個相當重要的函數就是print_stats——用以根據最後一次調用sort_stats之後得到的報表。 cProfile

python -m cProfile -s time test.py

timeit
如果我們某天心血來潮,想要向list裡append一個元素需要多少時間或者想知道拋出一個異常要多少時間,那使用profile就好像用牛刀殺雞了。這時候我們更好的選擇是timeit模塊。
timeit除了有非常友好的編程接口,也同樣提供了友好的命令行接口。首先來看看編程接口。timeit模塊包含一個類Timer,它的構造函數是這樣的: class Timer( [stmt='pass' [, setup='pass' [, timer=<timer function>]]]) stmt參數是字符串形式的一個代碼段,這個代碼段將被評測運行時間;setup參數用以設置stmt的運行環境;timer可以由用戶使用自定義精度的計時函數。 timeit.Timer有三個成員函數,下面簡單介紹一下: timeit( [number=1000000]) timeit()執行一次Timer構造函數中的setup語句之後,就重復執行number次stmt語句,然後返回總計運行消耗的時間。 repeat( [repeat=3 [, number=1000000]]) repeat()函數以number為參數調用timeit函數repeat次,並返回總計運行消耗的時間 print_exc( [file=None]) print_exc()函數用以代替標准的tracback,原因在於print_exc()會輸出錯行的源代碼,如: >>> t = timeit.Timer("t = foo()/nprint t") ß被timeit的代碼段 >>> t.timeit() Traceback (most recent call last): File "<pyshell#12>", line 1, in -toplevel- t.timeit() File "E:/Python23/lib/timeit.py", line 158, in timeit return self.inner(it, self.timer) File "<timeit-src>", line 6, in inner foo() ß標准輸出是這樣的 NameError: global name 'foo' is not defined >>> try: t.timeit() except: t.print_exc() Traceback (most recent call last): File "<pyshell#17>", line 2, in ? File "E:/Python23/lib/timeit.py", line 158, in timeit return self.inner(it, self.timer) File "<timeit-src>", line 6, in inner t = foo() ßprint_exc()的輸出是這樣的,方便定位錯誤 NameError: global name 'foo' is not defined 除了可以使用timeit的編程接口外,我們也可以在命令行裡使用timeit,非常方便: python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...] 其中參數的定義如下: -n N/--number=N statement語句執行的次數 -r N/--repeat=N 重復多少次調用timeit(),默認為3 -s S/--setup=S 用以設置statement執行環境的語句,默認為”pass” -t/--time 計時函數,除了Windows平台外默認使用time.time()函數, -c/--clock 計時函數,Windows平台默認使用time.clock()函數 -v/--verbose 輸出更大精度的計時數值 -h/--help 簡單的使用幫助
Copyright © Linux教程網 All Rights Reserved