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

队列使用者打印与日志记录[重复]

  •  1
  • Matej  · 技术社区  · 7 年前

    在调试下面的队列示例时,我发现了一个奇怪的行为(对我来说)与Python3.6中的print函数有关。下面的代码按预期工作,但是,如果我在下面的消费者函数中将“logger.info”更改为“print”函数,消费者函数将挂起。为什么会这样?

    from queue import Queue
    from threading import Thread
    import logging
    
    logging.basicConfig(format='%(asctime)s; %(name)s; %(levelname)s; %(message)s', level=logging.DEBUG)
    logger = logging.getLogger(__name__)
    logger.info('Starting...')
    
    
    def consumer(q):
        while True:
            item = q.get()
            logger.info ("Working on item: {}".format(item))
    
    
    def main():
        q = Queue()
    
        t = Thread(target=consumer, args=(q,))
        t.start()
    
        for i in range(3):
            q.put(i)
    
    if __name__ == '__main__':
        main()
    

    输出1:

    2018-02-20 09:24:29,630; __main__; INFO; Starting...
    2018-02-20 09:24:29,631; __main__; INFO; Working on item: 0
    2018-02-20 09:24:29,631; __main__; INFO; Working on item: 1
    2018-02-20 09:24:29,631; __main__; INFO; Working on item: 2
    

    输出2:

    2018-02-20 09:26:14,497; __main__; INFO; Starting...
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Ilija    7 年前

    可能是因为 stdout 缓冲。

    在Python 3中。你有额外的参数 flush 用于打印功能。它是 False 默认情况下。可能会设置为 True 将刷新输出缓冲区。

    然而,我想指出的是:

    logger.info ("Working on item: {}".format(item))
    

    你不应该 format 字符串并以这种方式形成日志消息。

    正确的做法是:

    logger.info("Working on item: %s", item)
    

    或者也许

    logger.info("Working on item: {item}", item=item)
    

    原因:最好推迟日志消息的创建,直到真正需要它,如果需要的话。

    你可以找到更多关于它的信息 here .