当前位置:首页>python>你还在用 print 调试?Python logging 模块才是正经工具

你还在用 print 调试?Python logging 模块才是正经工具

  • 2026-10-02 21:44:26
你还在用 print 调试?Python logging 模块才是正经工具
同事小马最近接了个数据处理的需求,写了个脚本,跑得挺顺。上线第一天,线上报了个错,他赶紧加了一堆 print 看问题在哪。

结果第二天上线,日志文件里全是这种输出,真正出错的那行反而被淹没了。

更要命的是,他想关掉这些调试信息,发现得一个一个手动删。

这就是 print 调试的终极问题:调试信息和业务日志混在一起,想关关不掉,想找找不到。


1. logging 模块:Python 自带的日志系统

logging 模块是 Python 标准库自带的,零依赖,不用装。

它解决的核心问题是:让程序的输出分级别、分去向、可控制。

几个关键概念:

  • Logger:日志的入口,你调 logging.info() 实际上是在调 logger 的方法

  • Handler:日志往哪送,控制台、文件、网络都行

  • Formatter:日志长什么样,时间、级别、模块名都可以自定义

  • Level:日志的紧急程度,DEBUG < INFO < WARNING < ERROR < CRITICAL

跟 print 比,logging 的区别在哪里?

维度printlogging
级别区分没有,全混在一起5 级,按紧急程度过滤
输出去向只能打控制台控制台、文件、网络、邮件都行
运行时控制要改代码删 print改配置就行,不碰业务代码
格式化自己拼字符串内置模板,时间/线程/模块名自动带


2. 从 print 到 logging 的三步迁移

第一步:导包与基础设置

import logginglogging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s')logging.info('程序启动')logging.warning('配置文件不存在,使用默认值')logging.error('数据库连接失败')

输出:

2026-08-19 10:30:01 [INFO] 程序启动2026-08-19 10:30:01 [WARNING] 配置文件不存在,使用默认值2026-08-19 10:30:01 [ERROR] 数据库连接失败

第二步:输出到文件

import logginglogging.basicConfig(    level=logging.DEBUG,    format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',    handlers=[        logging.FileHandler('app.log', encoding='utf-8'),        logging.StreamHandler()    ])

第三步:按模块分 logger(生产推荐)

import logginglogger = logging.getLogger(__name__)def process_data(data):    logger.info('收到 %d 条数据', len(data))    try:        result = transform(data)        logger.info('处理完成,输出 %d 条', len(result))        return result    except Exception as e:        logger.error('处理失败: %s', e, exc_info=True)        raise

exc_info=True 会把完整的错误堆栈打出来,比 print 的 print(e) 强太多了。


3. logging 的设计思想

logging 的核心设计思路是关注点分离:

  • 业务代码只管说发生了什么,不管输出到哪

  • 配置层决定日志去控制台还是文件、输出什么格式

  • 运行时通过调整 level 过滤不需要的信息

这意味着:开发环境设 DEBUG 看详细日志,生产环境切 INFO 只看关键信息,业务代码一行不用改。

还有一个容易被忽略的设计:logger 是层级的。

logging.getLogger('app.db') 是 logging.getLogger('app') 的子 logger。

你可以给 app 设一个级别,单独给 app.db 设另一个级别,精细控制每个模块的日志量。


4. 常见问题

basicConfig 调了两次不生效?

是的,basicConfig 只在第一次调用时生效。第二次调用会被忽略。所以一般在程序入口调一次就够了,别到处写。

logging 和 print 混着用会乱吗?

会。

print 输出没有时间戳和级别,跟 logging 的输出混在一起很难看。要么全用 logging,要么至少在生产代码里把 print 换掉。

多线程环境下 logging 安全吗?

安全。

logging 内部做了锁,多线程同时写日志不会交错。print 在多线程下反而可能输出交错。

把 print 换成 logging,是每个Python开发者从脚本走向工程的第一步。配置三行代码,换来的是可控制、可追溯、可搜索的日志体系。

欢迎大家评论区留言讨论~


我是鲁叶的Python,10年互联网古法程序员。

Python/ML/DL/大模型都折腾过,坑也踩了不少。

关注我,持续输出实用干货。

最新文章

随机文章