You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多模块Python包日志切换:主程序与API导入时的日志策略实现

优雅实现Python包的日志动态配置

核心思路

利用Python日志模块的层级继承特性,包内所有子模块通过__name__获取日志器,自动继承根日志器的配置。只需在main.py中根据运行场景(直接执行/被导入)动态配置根日志器,无需在各模块重复配置或传递日志器,完美避开多日志器写同一文件的问题。

具体实现步骤

1. 包内子模块的日志使用规范

所有子模块统一用logging.getLogger(__name__)获取日志器,不需要额外配置:

# 示例:包内的module_a.py
import logging

logger = logging.getLogger(__name__)

def do_something():
    logger.info("模块A执行了核心操作")

2. main.py中的动态配置逻辑

通过__name__ == "__main__"判断运行模式,结合命令行参数决定日志输出方式:

import logging
import argparse
from my_package import module_a, module_b

def setup_logging(log_file=None):
    # 获取根日志器,统一管理所有子模块的日志配置
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.INFO)

    # 清空已有处理器,避免重复添加导致日志重复输出
    for handler in root_logger.handlers[:]:
        root_logger.removeHandler(handler)

    # 配置控制台输出处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    console_handler.setFormatter(formatter)
    root_logger.addHandler(console_handler)

    # 如果传入日志文件参数,添加文件输出处理器
    if log_file:
        file_handler = logging.FileHandler(log_file, encoding="utf-8")
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(formatter)
        root_logger.addHandler(file_handler)

if __name__ == "__main__":
    # 解析命令行的日志文件参数
    parser = argparse.ArgumentParser()
    parser.add_argument("--log-file", help="日志输出文件的路径")
    args = parser.parse_args()

    # 初始化日志配置
    setup_logging(args.log_file)

    # 调用包内模块的功能
    module_a.do_something()
    module_b.do_something_else()
else:
    # 当包被其他代码导入时,仅配置控制台输出
    setup_logging()

方案优势

  • 无需传递日志器:子模块通过层级继承自动复用根日志器配置,符合Python日志模块的设计规范。
  • 避免文件句柄冲突:仅根日志器添加文件处理器,所有子模块日志统一通过该处理器输出,不会出现多进程写同一文件的问题。
  • 场景自动适配:通过__name__判断运行模式,自动切换日志配置,逻辑简洁清晰。
  • 配置集中可控:所有日志配置逻辑都在setup_logging函数中,后续修改格式、级别等只需调整这一处。

注意事项

  • 子模块中不要自行添加日志处理器,否则会破坏继承关系,导致日志重复输出。
  • 如果需要某子模块单独设置日志级别,直接在子模块中写logger.setLevel(logging.DEBUG)即可,不会影响其他模块的配置。

内容的提问来源于stack exchange,提问作者Olga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:57:22