【问题标题】:Should a Python logger be passed as parameter? [closed]是否应该将 Python 记录器作为参数传递? [关闭]
【发布时间】:2013-08-05 07:31:57
【问题描述】:

我们正在开发的 Python 应用程序需要一个记录器。一位同事认为应该在每个使用它的类中创建和配置记录器。我的意见是它应该在应用程序启动时创建和配置,并作为构造函数参数传递。

两种变体都有其优点,我们不确定最佳做法是什么。

【问题讨论】:

  • 只需要配置一次记录器,在其他类中只需导入记录模块即可。最好创建一个“configure_logging”函数(在单独的模块或主模块中),以便您可以导入此函数来测试类或模块。 (在if __name__ == "__main__"unittest 之后导入start_logging)
  • 这是有道理的,但是对于单元测试,我想模拟记录器,但我看不出这将如何与日志记录模块一起使用。
  • 为了更好地了解我的意思是如何实现记录器,我发布了一个带有示例的答案,希望对您有所帮助.. 当然这只是一个想法,我希望您找到适合您情况的最佳解决方案.

标签: python logging


【解决方案1】:

通常不会;它通常不打算作为参数传递。

约定是在每个模块的顶部使用log = logging.getLogger(__name__)__name__ 的值因每个模块而异。然后,__name__ 的结果值可以反映在每条日志消息中。

【讨论】:

    【解决方案2】:

    也许这可以帮助您获得一个想法?当然,您可以做得更好,从配置文件中读取设置或其他任何内容,但这是一个简单的示例。

    用于配置日志记录的单独模块:mylogmod.py

    import logging
    
    FILENAME = "mylog.log" # Your logfile
    LOGFORMAT = "%(message)s" # Your format
    DEFAULT_LEVEL = "info" # Your default level, usually set to warning or error for production
    LEVELS = {
        'debug':logging.DEBUG,
        'info':logging.INFO,
        'warning':logging.WARNING,
        'error':logging.ERROR,
        'critical':logging.CRITICAL}
    
    def startlogging(filename=FILENAME, level=DEFAULT_LEVEL):
        logging.basicConfig(filename=filename, level=LEVELS[level], format=LOGFORMAT)
    

    main.py

    import logging
    from mylogmod import startlogging
    from myclass import MyClass
    
    startlogging()
    
    logging.info("Program started...")
    mc = MyClass()
    

    一个类myclass.py 来自一个带有自检的模块。您可以在单元测试中执行类似的操作:(请注意,您不需要在单元测试中导入日志模块,只需 startlogging 函数就足够了。这样您可以将默认级别设置为警告或错误以及单元测试和自测调试)

    import logging
    
    class MyClass(object):
        def __init__(self):
            logging.info("Initialze MyClass instance...")
    
    if __name__ == "__main__":
        from mylogmod import startlogging
        startlogging(level="debug")
        logging.debug("Test MyClass...")
        #... rest of test code...
    

    【讨论】:

    • 这是使用根记录器。任何与其他应用程序集成的复杂应用程序都不想使用根记录器。
    【解决方案3】:

    我认为将记录器作为参数传递并不是一个好主意。您应该将全局记录器视为自己的模块,这将是最好的主意。例如:
    logger.py

    import logging
    log = logging.getLogger('')
    

    classFoo.py

    form logger import log
    log.debug('debug message')
    

    classBar.py

    form logger import log
    log.warn('warn!')
    

    【讨论】:

    • 这也不是一个好主意,因为您现在总是使用名称为空字符串的记录器,而不是使用名称为 __name__ 的记录器。请看我的回答。
    猜你喜欢
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 2018-09-21
    相关资源
    最近更新 更多