代码之家  ›  专栏  ›  技术社区  ›  d33tah

logger应该是参数还是全局变量?

  •  6
  • d33tah  · 技术社区  · 6 年前

    在阅读Python代码时,我通常会看到这两种约定之一:

    def something(logger):
      logger.info('doing something')
    

    或:

    LOGGER = logging.getLogger(__NAME__)
    def something():
      LOGGER.info('doing something')
    

    前者有什么优点吗,即线程安全而另一个不安全?还是纯粹的文体差异?

    1 回复  |  直到 5 年前
        1
  •  2
  •   MisterMiyagi    5 年前

    固定的

    LOGGER = logging.getLogger('stuff.do')
    
    # logger depends on what we are
    def do_stuff(operation: Callable):
        LOGGER.info('will do stuff')
        operation()
        LOGGER.info('just did stuff')
    
    do_stuff(add_things)
    do_stuff(query_things)
    

    如果需要,请使用记录器参数 改变 记录者:

    # logger depends on what we do
    def do_stuff(operation: Callable, logger: Logger):
        logger.info('will do stuff')
        operation()
        logger.info('just did stuff')
    
    do_stuff(add_things, logging.getLogger('add'))
    do_stuff(query_things, logging.getLogger('query'))
    

    这通常用于记录可配置操作以进行记帐。例如,web服务器将记录 不同种类


    如果记录器的选择可以全局决定,那么这样做可以避免由于记录器传递而污染函数签名。这提高了模块性,因为您可以添加/删除 logging 调用而不更改其他代码。当使用日志查找错误时,您可能希望将日志添加到可疑的代码部分,并将其从已验证的代码部分中删除。

    如果日志记录器的选择取决于本地状态,那么传递日志记录器或其名称通常是唯一的选择。当使用日志记录正在发生的事情时,有时需要在以后添加新类型的操作主题。


    登录中 模块设计为线程安全:

    Thread Safety

    日志模块是线程安全的,没有 客户需要做的特殊工作。它实现了这一点 模块共享数据,每个处理程序还创建一个 序列化对其底层I/O的访问。

    >>> a = logging.getLogger('demo')
    >>> b = a
    >>> c = logging.getLogger('demo')
    >>> a is b is c
    True