Python多模块项目CLI传入日志级别参数不生效,如何调整项目结构?
解决方案
方案1:调整__init__.py的逻辑,移除顶层执行代码
__init__.py的定位是包的初始化声明文件,原则上不应该存放直接执行的业务逻辑(包括日志输出)。你可以把原本在__init__.py顶层的日志代码移动到包内的初始化函数、类构造方法中,仅当业务代码主动调用对应逻辑时才执行,此时main函数已经完成了日志级别配置,不会出现日志级别不生效的问题。
优点:完全符合Python包设计规范,后续维护成本最低,是最推荐的方案。
方案2:调整main文件的导入顺序,符合PEP8规范
你不需要把import混在业务逻辑中间,只要调整导入分块顺序即可,完全符合PEP8的导入规范:
- 第一块仅导入Python标准库:
argparse、logging等 - 紧接着执行命令行参数解析,拿到日志级别配置
- 完成全局logging配置(可以直接配置根logger,所有子模块的logger默认会继承根logger的级别)
- 第二块导入第三方依赖库
- 第三块导入本地的
sub-module-1等业务模块
这种方式只是把业务模块的导入放到了参数和日志配置之后,所有导入语句依然集中在文件前半部分,不属于“import和业务代码混写”。
优点:不需要调整子模块代码,改造成本极低。
方案3:临时屏蔽导入阶段的日志输出
如果你既不能改__init__.py的逻辑,也不想调整导入顺序,可以用日志配置覆盖的方式处理:
- main最开头先将根logger的默认级别设置为
CRITICAL,同时禁用 propagate,这样导入阶段所有低于CRITICAL级别的日志都不会输出 - 解析完命令行参数后,调用
logging.basicConfig(level=你的目标级别, force=True)(Python3.8及以上支持force参数),强制重置所有已创建的logger的配置,后续日志就会按照你设置的级别输出
如果需要兼容低版本Python,可以遍历logging.root.manager.loggerDict把所有已存在的logger的级别统一重置。
优点:不需要调整现有业务逻辑和导入顺序,适配性强。
内容的提问来源于stack exchange,提问作者maephisto
相关产品推荐
相关产品推荐

