Python中10大高階調(diào)試方法分享
前言
調(diào)試是每個(gè)Python開(kāi)發(fā)者必備的核心技能。掌握高效的調(diào)試方法可以顯著提升開(kāi)發(fā)效率和代碼質(zhì)量。本文將介紹Python中最實(shí)用的10種高階調(diào)試技巧,幫助你快速定位和解決各種復(fù)雜的bug。
1. pdb:Python自帶的調(diào)試器
pdb是Python標(biāo)準(zhǔn)庫(kù)中的調(diào)試器,功能強(qiáng)大但常被忽視。
import pdb def problematic_function(x, y): result = x * y pdb.set_trace() # 設(shè)置斷點(diǎn) return result + 10 problematic_function(3, 4)
常用命令:
- n(ext): 執(zhí)行下一行
- s(tep): 進(jìn)入函數(shù)調(diào)用
- c(ontinue): 繼續(xù)執(zhí)行直到下一個(gè)斷點(diǎn)
- l(ist): 查看當(dāng)前代碼上下文
- p(rint): 打印變量值
- q(uit): 退出調(diào)試器
2. 斷點(diǎn)函數(shù):Python 3.7+的現(xiàn)代調(diào)試方式
Python 3.7引入了breakpoint()內(nèi)置函數(shù),替代了傳統(tǒng)的pdb.set_trace()。
def modern_debugging(): x = 10 y = 20 breakpoint() # 自動(dòng)使用最佳調(diào)試器 return x + y
可以通過(guò)設(shè)置PYTHONBREAKPOINT環(huán)境變量來(lái)指定調(diào)試器:
export PYTHONBREAKPOINT=ipdb.set_trace # 使用ipdb
3. 日志調(diào)試:logging模塊的高級(jí)用法
日志是長(zhǎng)期運(yùn)行程序的最佳調(diào)試伴侶。
import logging logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', filename='app.log' ) logger = logging.getLogger(__name__) def log_example(): try: result = 10 / 0 except Exception as e: logger.exception("發(fā)生了除零錯(cuò)誤: ") raise
高級(jí)技巧:
使用logging.config.dictConfig進(jìn)行復(fù)雜配置
為不同模塊設(shè)置不同日志級(jí)別
使用RotatingFileHandler實(shí)現(xiàn)日志輪轉(zhuǎn)
4. 斷言調(diào)試:assert的高級(jí)用法
斷言不僅是測(cè)試工具,也是強(qiáng)大的調(diào)試手段。
def process_data(data): assert isinstance(data, dict), "data必須是字典" assert 'key' in data, "data必須包含'key'" # 復(fù)雜斷言 assert all(isinstance(x, (int, float)) for x in data.values()), "所有值必須是數(shù)字" return {k: v*2 for k, v in data.items()}
優(yōu)化技巧:
使用-O參數(shù)運(yùn)行Python可以禁用斷言
為斷言添加描述性消息
避免在斷言中有副作用
5. 跟蹤函數(shù)調(diào)用:sys.settrace
sys.settrace允許你跟蹤Python程序的執(zhí)行流程。
import sys def trace_calls(frame, event, arg): if event == 'call': filename = frame.f_code.co_filename lineno = frame.f_lineno funcname = frame.f_code.co_name print(f"調(diào)用: {funcname} at {filename}:{lineno}") return trace_calls sys.settrace(trace_calls) def example_function(): print("函數(shù)內(nèi)部") example_function() sys.settrace(None) # 禁用跟蹤
6. 性能調(diào)試:cProfile和line_profiler
cProfile: 函數(shù)級(jí)性能分析
import cProfile def slow_function(): total = 0 for i in range(1000000): total += i return total cProfile.run('slow_function()')
line_profiler: 行級(jí)性能分析
安裝:
pip install line_profiler
使用:
# 在函數(shù)前添加裝飾器 @profile def slow_function(): total = 0 for i in range(1000000): total += i return total
運(yùn)行:
kernprof -l -v script.py
7. 內(nèi)存調(diào)試:objgraph和tracemalloc
objgraph: 對(duì)象引用可視化
import objgraph x = [] y = [x, [x], {'x': x}] objgraph.show_backrefs([x], filename='backrefs.png')
tracemalloc: 內(nèi)存分配跟蹤
import tracemalloc tracemalloc.start() # 你的代碼 data = [dict(zip('abc', (1, 2, 3))) for _ in range(100000)] snapshot = tracemalloc.take_snapshot() top_stats = snapshot.statistics('lineno') for stat in top_stats[:10]: print(stat)
8. 異常鉤子:sys.excepthook
自定義未捕獲異常的處理方式。
import sys def custom_excepthook(exc_type, exc_value, exc_traceback): print("!!! 未捕獲異常 !!!", file=sys.stderr) print(f"類型: {exc_type}", file=sys.stderr) print(f"值: {exc_value}", file=sys.stderr) # 可以在這里添加日志記錄、錯(cuò)誤報(bào)告等 sys.excepthook = custom_excepthook # 測(cè)試 1 / 0
9. 交互式調(diào)試:IPython的embed
在代碼中直接啟動(dòng)IPython shell。
from IPython import embed def complex_calculation(a, b): result = a * b if result > 100: embed() # 進(jìn)入IPython shell return result complex_calculation(50, 3)
10. 可視化調(diào)試:PyCharm/VSCode的調(diào)試器
現(xiàn)代IDE提供了強(qiáng)大的圖形化調(diào)試功能:
條件斷點(diǎn):只在滿足條件時(shí)暫停
表達(dá)式求值:在調(diào)試過(guò)程中計(jì)算任意表達(dá)式
遠(yuǎn)程調(diào)試:調(diào)試遠(yuǎn)程服務(wù)器上的代碼
多線程調(diào)試:跟蹤多個(gè)線程的執(zhí)行
結(jié)語(yǔ)
掌握這些高階調(diào)試技巧可以讓你在面對(duì)復(fù)雜bug時(shí)更加從容。記住,優(yōu)秀的開(kāi)發(fā)者不是不寫(xiě)bug,而是能夠快速找到并修復(fù)bug。根據(jù)不同的場(chǎng)景選擇合適的調(diào)試方法,將大幅提升你的開(kāi)發(fā)效率。
到此這篇關(guān)于Python中10大高階調(diào)試方法分享的文章就介紹到這了,更多相關(guān)Python調(diào)試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
tensorboard 可以顯示graph,卻不能顯示scalar的解決方式
今天小編就為大家分享一篇tensorboard 可以顯示graph,卻不能顯示scalar的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02Python實(shí)現(xiàn)批量合并Excel文件的第二張合并Excel
在數(shù)據(jù)處理和分析中,經(jīng)常需要對(duì)多個(gè)Excel文件進(jìn)行批量操作,特別是當(dāng)這些文件具有相似的結(jié)構(gòu)時(shí),下面我們就來(lái)看看Python如何實(shí)現(xiàn)批量合并文件夾下所有Excel文件的第二張表吧2024-03-03如何向scrapy中的spider傳遞參數(shù)的幾種方法
這篇文章主要介紹了如何向scrapy中的spider傳遞參數(shù)的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Python requests庫(kù)參數(shù)提交的注意事項(xiàng)總結(jié)
這篇文章主要給大家介紹了關(guān)于Python requests庫(kù)參數(shù)提交的注意事項(xiàng),文中通過(guò)示例代碼和圖片介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03使用Python腳本來(lái)獲取Cisco設(shè)備信息的示例
這篇文章主要介紹了編寫(xiě)Python腳本來(lái)獲取Python腳本來(lái)獲取Cisco設(shè)備信息的教程,文中的示例是獲取一臺(tái)思科交換機(jī)的腳本,需要的朋友可以參考下2015-05-05Python-Tkinter Text輸入內(nèi)容在界面顯示的實(shí)例
今天小編就為大家分享一篇Python-Tkinter Text輸入內(nèi)容在界面顯示的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07Python基本語(yǔ)法之運(yùn)算符功能與用法詳解
這篇文章主要介紹了Python基本語(yǔ)法之運(yùn)算符功能與用法,結(jié)合實(shí)例形式總結(jié)分析了Python常見(jiàn)運(yùn)算符相關(guān)使用技巧與操作注意事項(xiàng),需要的朋友可以參考下2019-10-10Python dash-fastapi前后端搭建過(guò)程
項(xiàng)目中需要快速搭建一個(gè)前后端系統(tǒng),涉及到dash-fastapi架構(gòu)的時(shí)候,對(duì)該架構(gòu)的時(shí)候進(jìn)行總結(jié),本文主要總結(jié)的是對(duì)該架構(gòu)的基本使用,后續(xù)再對(duì)該架構(gòu)的項(xiàng)目源碼進(jìn)行總結(jié)分析,感興趣的朋友一起看看吧2025-03-03