大家好,給大家分享一下一個有趣的事情,很多人還不知道這一點。下面詳細解釋一下。現在讓我們來看看!
對于每個程序開發者來說,調試幾乎是必備技能。常用Pycharm編輯器里的方法有Print大法、log大法,但缺少類似Matlab的變量區,給代碼調試帶來不便,特別是在有函數的情況下,變量無法實時查看火車采集器偽原創。
1、Python Console
在Pycharm編輯器里面有個Python Console,可以查看變量變化,但對于函數變量難調試。
2、PySnooper
安利一款非常好用的調試工具,它能在一些場景下,大幅度提高調試的效率, 那就是 PySnooper
2.1、快速安裝
執行下面這些命令進行安裝 PySnooper
pip install pysnooper
2.2、簡單案例
下面這段代碼,定義了一個?test?的函數,在里面生成一個?person 的字典變量,然后去更新它,最后返回。
import pysnooper
@pysnooper.snoop()
def test():
person = {}
person["name"] = "domi"
person["age"] = 28
person["gender"] = "male"
return person
def main():
author = test()
main()
輸出結果
21:25:21.875841?call?????????5?def?test():
21:25:21.875841 line 6 person = {}
New var:....... person = {}
21:25:21.875841 line 7 person["name"] = "domi"
Modified var:.. person = {'name': 'domi'}
21:25:21.876840 line 8 person["age"] = 28
Modified var:.. person = {'name': 'domi', 'age': 28}
21:25:21.876840 line 9 person["gender"] = "male"
Modified var:.. person = {'name': 'domi', 'age': 28, 'gender': 'male'}
21:25:21.876840 line 10 return person
21:25:21.876840 return 10 return person
Return value:.. {'name': 'domi', 'age': 28, 'gender': 'male'}
Elapsed time: 00:00:00.000999
PySnooper 把函數運行的過程全部記錄了下來,包括:
-
代碼的片段、行號等信息,以及每一行代碼是何時調用的?
-
函數內局部變量的值如何變化的?何時新增了變量,何時修改了變量。
-
函數的返回值是什么?
-
運行函數消耗了多少時間?
2.3、重定向到日志文件
@pysnooper.snoop() 不加任何參數時,會默認將調試的信息輸出到標準輸出。對于單次調試就能解決的 BUG ,這樣沒有什么問題,但是有一些 BUG 只有在特定的場景下才會出現,需要你把程序放在后面跑個一段時間才能復現。這種情況下,你可以將調試信息重定向輸出到某一日志文件中,方便追溯排查。
@pysnooper.snoop(output='./debug.log')
def test():
2.4、跟蹤非局部變量值
PySnooper 是以函數為單位進行調試的,它默認只會跟蹤函數體內的局部變量,若想跟蹤全局變量,可以給 pysnooper.snoop() 加上 watch 參數
out = {"foo": "bar"}
@pysnooper.snoop(watch=('out["foo"]'))
def test():
person = {}
person["name"] = "domi"
person["age"] = 28
person["gender"] = "male"
out["foo"] += 'test'
return person
2.5、設置跟蹤函數的深度
當你使用 PySnooper 調試某個函數時,若該函數中還調用了其他函數,PySnooper 是不會傻傻的跟蹤進去的。如果你想繼續跟蹤該函數中調用的其他函數,可以通過指定 depth 參數來設置跟蹤深度(不指定的話默認為 1)。
@pysnooper.snoop()
def test():
person = {}
person["name"] = "domi"
person["age"] = 28
person["gender"] = "male"
c = test1()
return person
def test1():
a = 1
b = 2
return a + b
@pysnooper.snoop(depth=2)
2.6、設置調試日志的前綴
當你在使用 PySnooper 跟蹤多個函數時,調試的日志會顯得雜亂無章,不方便查看。在這種情況下,PySnooper 提供了一個參數,方便你為不同的函數設置不同的標志,方便你在查看日志時進行區分。
@pysnooper.snoop(output="./debug.log", prefix="test: ")
def test():
person = {}
person["name"] = "domi"
person["age"] = 28
person["gender"] = "male"
c = test1()
return person
@pysnooper.snoop(output="./debug.log", prefix="test1: ")
def test1():
a = 1
b = 2
return a + b
2.7、支持多線程調試模式
PySnooper 同樣支持多線程的調試,通過設置參數 thread_info=True,它就會在日志中打印出是在哪個線程對變量進行的修改。
@pysnooper.snoop(thread_info=True)