Python 调试中 print 与 logging 的选择
技术百科
冷炫風刃
发布时间:2026-01-21
浏览: 次 调试时临时验证用print,正式场景必须用logging;print适合开发初期快速探路,logging提供分级、定向、格式化和可维护的日志能力。
调试时该用 print 还是 logging,关键看阶段和需求:临时快速验证用 print 更轻量;需要留存、分级、控制输出或上线后仍需可观测性时,必须用 logging。
什么时候直接用 print 就够了
print 适合开发初期的“探路式”调试——比如刚写完一个函数,想立刻确认输入输出是否符合预期,或者快速定位某行代码有没有执行到

- 无需配置,一行就出结果,改完删掉也方便
- 配合 f-string(如
print(f"x={x}, type={type(x)}"))能清晰看到变量值和类型 - 在 Jupyter 或交互式环境里,
print的即时反馈比配置 logger 更顺手
为什么 logging 在多数正式场景更可靠
logging 不是“高级版 print”,而是为可维护性设计的日志系统。它解决的是 print 天然不具备的能力:
-
级别控制:用
logger.debug()记细节,logger.warning()标异常倾向,logger.error()报错误,上线时可一键关闭 debug 日志,不影响性能 -
输出定向:日志既能打到控制台,也能自动写入文件,还能发到远程服务,
print只能 stdout/stderr -
格式统一:自带时间戳、模块名、行号(如
2025-06-15 10:23:41,123 - mymodule.py:42 - INFO - 数据加载完成),排查问题时不用再手动拼接 -
避免误提交:团队协作中,
print很容易被遗忘并随代码上线,而 logging 默认级别设为 WARNING 以上时,debug 日志天然静默
一个务实的过渡建议
不必从第一行代码就上完整 logging 配置。可以这样渐进使用:
- 先用
logging.basicConfig(level=logging.DEBUG)快速启用基础日志,体验和print差不多的写法(logging.debug("x=%r", x)) - 把频繁修改/删除的
print替换为logging.debug(),保留逻辑但获得可开关性 - 当项目结构变复杂,或需要区分模块日志时,改用命名 logger:
logger = logging.getLogger(__name__),避免全局污染 - 上线前,在入口处设置
logging.basicConfig(level=logging.WARNING),debug 和 info 日志自动消失,无需逐行删 print
别忽略的细节
用 logging 时几个易错点:
-
不要用字符串拼接传参:写
logging.debug("value=%s", x),而不是logging.debug("value=" + str(x))。前者在日志关闭时不会计算str(x),更高效 -
避免在日志里调用可能抛异常的函数:比如
logging.info("len=%d", len(obj)),如果obj不支持len(),日志还没打出就崩溃了 -
DEBUG 级别日志默认不显示:运行脚本时若没设 level,只看到 WARNING 及以上,记得加
basicConfig(level=logging.DEBUG)
# 的是
# 几个
# 也能
# 还能
# python
# 很容易
# 什么时候
# 还没
# 设为
# 不支持
# Error
# String
# 字符串
# 为什么
# 行号
# asic
# len
# print
# Logging
# jupyter
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win10如何优化内存使用_Win10内存优化技巧
- Win10如何卸载预装Edge扩展_Win10卸载
- 如何在Golang中修改数组元素_通过指针实现原地
- Win11怎么设置屏保_Windows 11屏幕保
- Win11怎么设置快速访问主页_Windows11
- Windows服务无法启动错误1067是什么_进程
- Win11触摸板没反应怎么办_开启Win11笔记本
- Win10怎样安装PPT模板_Win10安装PPT
- Win11无法安装软件怎么办_Win11解除应用安
- Python函数参数高级用法_默认值与可变参数解析
- 如何使用Golang实现Web表单数据绑定_自动映
- php中::能用于接口静态方法吗_接口静态方法调用
- Win11蓝牙开关不见了怎么办_Win11蓝牙驱动
- Go 中 := 短变量声明的类型推导机制详解
- 本地php环境出现502错误_nginx或apac
- 如何使用Golang安装依赖库_管理模块和第三方包
- Windows10怎么查看硬件信息_Windows
- Windows10怎样连接蓝牙设备_Windows
- XSLT怎么生成动态的HTML属性名和标签名
- 如何使用Golang编写单元测试_创建Test函数
- Win11怎么查看显卡显存_查询Win11显卡详细
- 如何在 ACF 中正确更新嵌套多层 Group 字
- Win11怎样激活系统密钥_Win11系统密钥激活
- Windows 11怎么更改锁屏超时时间_Wind
- 如何使用Golang实现容器自动化运维_Golan
- php怎么下载安装后无法解析php文件_服务器配置
- 如何在Mac上搭建Golang开发环境_使用Hom
- c# Task.Yield 的作用是什么 它和Ta
- 如何使用Golang recover捕获panic
- php中作用域操作符能访问私有静态属性吗_访问权限
- Win11怎么更改管理员名字 Win11修改账户名
- Python安全爬虫设计_IP代理池与验证码识别策
- Win11怎么设置默认终端应用_Windows11
- Windows怎样关闭开始菜单广告_Windows
- php打包exe怎么传递参数_命令行参数接收方法【
- Win11如何开启telnet服务 Win11启用
- 如何使用Golang sort排序切片_Golan
- Win10系统怎么查看端口状态_Windows10
- Win11怎么解压RAR文件 Win11自带解压功
- LINUX如何删除用户和用户组_Linux use
- c++获取当前时间戳_c++ time函数使用详解
- Win11关机界面怎么改_Win11自定义关机画面
- 如何使用Golang实现微服务事件驱动_使用消息总
- c++如何用AFL++进行模糊测试 c++ Fuz
- php删除数据怎么软删除_添加is_del字段标记
- 如何使用正则表达式批量替换重复的星号-短横模式为固
- 静态属性修改会影响所有实例吗_php作用域操作符下
- Win11开机自检怎么关闭_跳过Win11开机磁盘
- c++如何实现多态性_c++ 虚函数表原理与动态绑
- c++中如何进行二进制文件读写_c++ read与

QQ客服