logging.info()不打印是因为根logger默认级别为WARNING且未配置handler;需调用basicConfig或显式添加带Formatter的Handler,并注意logger与handler的双重级别控制。

Python 的 logging 模块默认只输出 WARNING 及以上级别日志,如果你写了 logging.info("启动完成") 却没看到输出,不是代码错了,是日志级别没调对,也没配 handler。
为什么 logging.info() 不打印?
因为根 logger 的默认级别是 WARNING,INFO 和 DEBUG 被直接拦截。同时,若没显式添加 handler(比如 StreamHandler),日志甚至不会被输出到终端。
- 调用
logging.basicConfig()是最简方式,但它只在第一次调用时生效,后续再调无效 - 必须在任何
logging.debug/info/warning之前设置,否则已被跳过 -
level参数要设成你希望最低可见的级别,比如想看INFO,就得写level=logging.INFO
如何为不同模块设置不同日志级别?
不要只依赖根 logger;每个模块应获取自己的 logger 实例,用 __name__ 命名,再单独设级别和 handler。这样主模块可设 INFO,而第三方库(如 requests)的日志可设为 WARNING 以减少干扰。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 用
logger = logging.getLogger(__name__)获取命名 logger,避免污染根 logger - 调用
logger.setLevel(logging.DEBUG)设置该 logger 的阈值(注意:不等于输出级别,只是“准入门槛”) - handler 自己也要调
setLevel(),比如handler.setLevel(logging.INFO)—— 日志需同时满足 logger 和 handler 的级别才输出 - 多个 handler 可共存:一个输出到终端(
INFO),一个写入文件(DEBUG)
怎么让日志带时间、模块名和行号?
靠 Formatter。默认格式太简陋,没有上下文很难定位问题。别用字符串拼接,用 %(asctime)s 这类标准占位符,它们由 logging 内部填充,线程安全且支持毫秒。
- 推荐格式字符串:
%(asctime)s | %(levelname)-8s | %(name)s:%(lineno)d | %(message)s -
%(asctime)s默认不含毫秒,加datefmt='%Y-%m-%d %H:%M:%S.%f'并截断微秒([:-3])更实用 - handler 必须显式绑定 formatter:
handler.setFormatter(formatter),漏掉这步就还是默认格式 - 如果用
basicConfig,可通过format和datefmt参数一次性配置,但灵活性差
真正容易出问题的不是语法,而是 logger 层级继承关系和 handler 的独立 level 控制——同一个日志消息可能被多个 handler 处理,每个 handler 都有自己的过滤逻辑。调试时建议先关掉所有第三方库 logger(logging.getLogger("requests").setLevel(logging.WARNING)),再逐个放开,否则日志会淹没关键信息。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










