
我刚开始学 Python 那会儿,每次代码报错都只会干两件事:第一,看报错信息;第二,在可疑的地方插一行 print("here")。
说实话,这一招当时真的帮我解决了 80% 的问题。但写多了就发现,print 用法太糙,遇到复杂点的场景——比如循环里某个变量悄悄变味了、或者函数嵌套好几层——纯靠 print 就开始抓瞎。
后来工作里被同事教了几招"print 的花式玩法",我才知道:原来 print 不只是 print,用对了它能当半个调试器。今天把这 5 个用法整理出来,新手看完能直接上手,老手也能查漏补缺。
在开始之前先说一个原则:print 调试不是丢人的事。很多大厂程序员在排查生产环境问题时,第一反应也是插日志看输出。区别在于,他们 print 的方式比新手更聪明。
一、给 print 加个"名字"——定位变量是哪个文件哪一行
新手最常写的 print 长这样:
count = 10
print(count)
输出就是光秃秃的 10。如果项目里有十几个 print,过几小时回来排查,屏幕上全是 10、20、30,根本分不清哪个 print 来自哪段代码。
解决方法是给 print 加个"前缀":
count = 10
print(f"[用户模块-计算行] count = {count}")
这样输出就是 "[用户模块-计算行] count = 10",一眼就知道这个值是从哪冒出来的。
再进一步,可以用 f-string 把变量名和值一起打出来:
name = "小白"
age = 25
print(f"{name=}, {age=}")
输出:
name='小白', age=25
注意那个 {name=} 的写法。这是 Python 3.8 引入的"自调试 f-string"——变量名会自动被打印出来,连同它的值。不用再写 f"name={name}" 那么啰嗦。
这个技巧看似小,但能救命:当你看到一个莫名其妙的结果时,变量名+值一起输出,能立刻确认"哦,这个变量在这一步是 X,但我以为它应该是 Y"。
二、打印类型而不是值——揪出"看起来对"却其实错的数据
新手最常被坑的场景是"类型问题"。你以为是数字,结果是字符串;你以为是列表,结果是 None。打印值看不出来,打印类型一看一个准。
user_input = input("请输入年龄: ")
print(f"值: {user_input}, 类型: {type(user_input)}")
输出:
值: 25, 类型: <class 'str'>
看到没?input() 不管你输入什么,返回的都是字符串。如果你直接拿 user_input 做加法,结果就是把数字"拼接"起来,不是算术相加:
print("25" + 1) # 报错
print("25" + str(1)) # "251",拼接
这种坑 print 出来就是几行代码的事,但靠眼睛看永远看不出来——屏幕上都是"25",你分不清它到底是数字还是字符串。
进阶玩法:打印 None 的时候也加上类型检查,因为 None 在打印时什么也不输出,特别容易漏掉:
result = some_function()
print(f"result = {result!r}, 类型 = {type(result)}")
那个 {result!r} 不是手滑写错了,是 Python 的"repr"格式化:字符串会带引号打印("25" 而不是 25),None 也会显示出 "None"。这样不会因为打印空内容而错过关键信息。
三、用 print 当断点——确认代码到底走没走到这一步
新手常遇到一种情况:明明写了 if 分支,但走进 if 后面的代码就是不执行。这种时候,先别怀疑逻辑,先确认代码到底有没有走到那里。
def process(data):
print("[1] 进入 process 函数")
if not data:
print("[2] data 是空的,直接返回")
return
print("[3] data 不为空,开始处理")
result = transform(data)
print(f"[4] transform 返回: {result}")
return result
运行的时候看输出打到哪一步:[1] 出现了但 [2] 没出现?说明 if 条件判断错了。[4] 没出现?说明 transform 里崩了。这种"流程追踪"是 print 调试的精髓。
更专业的做法是用 logging 模块的级别(DEBUG、INFO、WARNING),但对新手来说,先把 print 玩明白就够用。
小技巧:在循环里打印时,加上循环变量:
for i, item in enumerate(items):
print(f"[循环 {i}] item = {item!r}")
这样不仅能看到当前 item 是什么,还能看到是第几次循环出的问题。调试列表处理、字典遍历的时候特别好用。
四、用 print 看出字典/列表里到底是什么——避免"看花眼"
当你打印一个字典或者列表,有时候输出会变成这种鬼样子:
{'user': {'profile': {'name': '小白', 'tags': ['python', 'beginner']}, 'settings': {...}}}
嵌套深一点的字典,print 出来的结果就是一行到底,眼睛根本看不出来结构。解决方法是 pprint(pretty print 的缩写):
from pprint import pprint
user = {
"name": "小白",
"profile": {
"age": 25,
"tags": ["python", "beginner"]
},
"settings": {
"theme": "dark",
"notifications": True
}
}
pprint(user)
输出:
{'name': '小白',
'profile': {'age': 25, 'tags': ['python', 'beginner']},
'settings': {'notifications': True, 'theme': 'dark'}}
结构是不是清晰多了?字典里嵌套了什么、列表里有几个元素,一目了然。
更狠一点的玩法——如果对象太大,可以只打印你关心的字段:
# 列表很大,只想看前 3 个
print("前3个:", items[:3])
# 字典太大,只看某几个 key
print("关心的字段:", {k: user[k] for k in ["name", "age"]})
比起把整个对象一股脑全 print 出来,这样更有针对性,也更容易看出问题在哪。
五、用 print 配合 sys._current_frames() 抓"消失的现场"
最后这一招比较"黑科技",适合解决一种特殊场景:程序跑到一半突然报错,但你想看报错那一刻所有变量的状态。
Python 内置了一个 traceback 模块,能在 except 里抓到当前的调用栈。但要更狠地抓"所有局部变量",得用 sys._current_frames():
import sys
import traceback
def deep_function(x):
y = x * 2
z = y + "字符串" # 这里会报错
return z
def caller():
result = deep_function(10)
return result
try:
caller()
except Exception:
print("程序出错了!当前所有局部变量:")
for tid, frame in sys._current_frames().items():
print(f" 线程 {tid} 在文件 {frame.f_code.co_filename}:{frame.f_lineno}")
print(f"函数: {frame.f_code.co_name}")
print(f"局部变量: {frame.f_locals}")
这样报错的时候,你能看到每一层函数里都有什么变量、值是什么。对调试那种"在 A 函数里设置、B 函数里修改、C 函数里用到,结果 C 函数炸了"的多层调用问题特别有效。
不过说实话,这招已经属于"print 调试的边界"了。掌握到这里,说明你已经把 print 玩出花来了。下一步该学的是断点调试器 pdb——在代码里打断点、单步执行、实时看变量。如果今天的内容看完觉得不过瘾,下一篇我就写 pdb。
最后帮你把这 5 个技巧压缩成一张速查表,方便收藏起来用:
1. 加标签:f"[模块-步骤] {var=}" → 区分多个 print 的来源
2. 看类型:print(type(var), var) → 排查"看起来对其实错"的数据
3. 当断点:在关键步骤加 print → 确认代码走到哪一步
4. 用 pprint:from pprint import pprint → 美化复杂结构输出
5. 抓现场:sys._current_frames() → 报错时打印所有变量状态
调试这件事,工具是死的,人是活的。IDE 的断点、pdb、日志框架都是好工具,但 print 永远是最快、最直接的那个。先把 print 玩明白,再去学高级工具,效率会高很多。
你平时调试 Python 代码,最常用的是什么方法?是用 print 大法,还是已经学会了断点调试?评论区聊聊你的调试习惯,我看看大家都卡在哪个环节。如果这篇内容对你有用,转发给身边刚开始学 Python 的朋友,他们一定用得上。
以上就是“Python调试时只会print?学会这5个进阶用法,新手也能秒变老手”的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。
扫码二维码 获取免费视频学习资料

- 本文固定链接: http://www.phpxs.com/post/14259/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料