在导入其他模块之前设置日志记录

dan*_*ast 7 python logging

在导入模块之前设置日志系统(格式、级别)的标准方法是什么?

我想这样做的原因是,在导入阶段会加载复杂的数据结构,并通过记录器显示进度。但由于未设置日志记录级别,我什至看不到这些日志条目(级别是默认的WARNING

我可以做这样的黑客:

import logging

logging.basicConfig(...)

import mymodule
Run Code Online (Sandbox Code Playgroud)

但我不喜欢在导入东西之前运行代码。

是否没有一种公认的方法可以使用环境变量或任何此类替代方案从应用程序外部“预配置”日志系统?就像是:

LOG_LEVEL=INFO LOG_FORMAT="..." python main.py
Run Code Online (Sandbox Code Playgroud)

我当然可以自己评估这些环境变量(此时我上面的黑客就足够好了),但我想在实现我自己的解决方案之前重用现有的想法。

wim*_*wim 1

据我所知,没有办法用不同的默认行为预先配置日志系统。最佳实践是避免在导入时配置日志记录 - 由用户决定适当的日志级别以及日志应发送到的位置(如果有)。为了使日志记录配置可配置,需要延迟到应用程序的入口点,而不是在导入时急切地配置。

库代码 ( mymodule) 不应假设存在有人正在监视输出的终端,甚至不应该假设存在可用于日志文件的可写文件系统。

我会推荐这种模式:

# main.py
import logging
import mymodule

def main():
    # parse cmdline args here
    logging.basicConfig(...)
    # or logging.config.fileConfig
    # or logging.config.dictConfig
    mymodule.init()
    # do work here

if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)

在库代码中:

# mymodule.py
import logging

log = logging.getLogger(__name__)

def init():
    log.info("loading complex data structures...")
Run Code Online (Sandbox Code Playgroud)

这可以避免将初始化日志事件丢弃,但在库代码中显式 init 调用还有另一个好处:可以通过参数init()或用户提供的配置文件来配置用于初始化的数据集。这意味着在测试期间,您可以从较小的缩小数据集加载,这样测试套件就不会运行缓慢。