关于 python-debugger
python-debugger 是为 Python 开发者提供的系统化排错技能,涵盖复现、定位、修复和验证。内容包括 traceback、pdb、日志、性能分析以及常见错误原因。
主要功能
- 01分步调试流程
- 02Traceback 分析
- 03复现与隔离问题的方法
- 04常见 Python 错误及修复思路
- 05日志与性能分析指导
- 06pdb 和错误类型参考
适用场景
- 01追踪异常的来源
- 02为缺陷创建最小复现用例
- 03使用 pytest 验证修复
- 04排查性能或内存问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill python-debugger安装后在 Claude Code 中输入/python-debugger确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/debug-checklist.mdpdb-commands.mdpython-error-types.md详细介绍
Python 调试器
调试流程
- 理解错误 -> 2. 复现 -> 3. 隔离问题 -> 4. 找出根本原因 -> 5. 修复 -> 6. 验证
步骤 1:理解错误
阅读回溯信息
Traceback (most recent call last): <- Read bottom to top
File "app.py", line 45, in main <- Entry point
result = process_data(data) <- Call chain
File "processor.py", line 23, in process_data
return transform(item) <- Getting closer
File "transformer.py", line 12, in transform
return item["value"] / item["count"] <- Error location
ZeroDivisionError: division by zero <- The actual error
常见错误类型:参见 references/python-error-types.md
步骤 2:复现问题
创建一个能触发错误的最小测试用例。回答以下问题:
- 什么输入触发了这个问题?
- 问题是持续出现还是偶尔出现?
- 问题从什么时候开始出现?
- 最近有哪些变化?
步骤 3:隔离问题
使用打印语句调试
def process_data(data):
print(f"DEBUG: data type = {type(data)}")
print(f"DEBUG: data = {data}")
for i, item in enumerate(data):
print(f"DEBUG: processing item {i}: {item}")
result = transform(item)
print(f"DEBUG: result = {result}")
return results
使用 pdb
import pdb
def problematic_function(x):
pdb.set_trace() # Execution stops here
# Or use: breakpoint() # Python 3.7+
result = x * 2
return result
pdb 命令:参见 references/pdb-commands.md
使用 icecream
from icecream import ic
def calculate(x, y):
ic(x, y) # Prints: ic| x: 5, y: 0
result = x / y
ic(result)
return result
步骤 4:常见根本原因
- None 值:访问属性前检查返回值。使用
if x is None: raise ValueError(...)进行保护 - 类型不匹配:添加类型提示,显式转换输入。使用
int(a) + int(b),而不是a + b - 可变默认参数:使用
def f(items=None):,然后在函数内执行items = items or [] - 循环导入:在函数内使用延迟导入:
from .module import Class - Async/await:缺少
await会返回协程,而不是结果 - 键/索引错误:字典使用
.get(key, default),列表检查len() - 作用域问题:检查
global/nonlocal声明,以及循环中的闭包变量捕获 - 编码:在
open()调用中指定encoding="utf-8" - 浮点精度:使用
decimal.Decimal或math.isclose()进行比较 - 资源泄漏:对文件、连接和锁使用
with语句
步骤 5:修复模式
防御式编程
def safe_divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
def safe_get(data: dict, key: str, default=None):
return data.get(key, default)
输入验证
def process_user(user_id: int, data: dict) -> dict:
if not isinstance(user_id, int) or user_id <= 0:
raise ValueError(f"Invalid user_id: {user_id}")
required_fields = ["name", "email"]
missing = [f for f in required_fields if f not in data]
if missing:
raise ValueError(f"Missing required fields: {missing}")
异常处理
import logging
logger = logging.getLogger(__name__)
def fetch_user_data(user_id: int) -> dict:
try:
response = api_client.get(f"/users/{user_id}")
response.raise_for_status()
return response.json()
except requests.HTTPError as e:
logger.error(f"HTTP error fetching user {user_id}: {e}")
raise
except requests.ConnectionError:
logger.error(f"Connection failed for user {user_id}")
raise ServiceUnavailableError("API unavailable")
步骤 6:验证修复
import pytest
def test_transform_handles_zero_count():
"""Verify fix for ZeroDivisionError."""
data = {"value": 10, "count": 0}
with pytest.raises(ValueError, match="count cannot be zero"):
transform(data)
def test_transform_normal_case():
"""Verify normal operation still works."""
data = {"value": 10, "count": 2}
result = transform(data)
assert result == 5
调试工具
日志设置
import logging
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s %(name)s %(levelname)s: %(message)s",
handlers=[
logging.FileHandler("debug.log"),
logging.StreamHandler(),
],
)
性能分析
# Time profiling
import cProfile
cProfile.run("main()", "output.prof")
# Memory profiling
from memory_profiler import profile
@profile
def memory_heavy_function():
# ...
使用 rich 改进输出效果
from rich.traceback import install
install(show_locals=True) # Enhanced tracebacks
参考资料
何时使用 WebSearch
- 难以理解的错误消息
- 特定库的错误
- 版本兼容性问题
- 未记录的行为
评论
支持 Markdown