Skip to main content
 首页 » 编程设计

python之为什么日志记录会进入无限循环

2025年05月04日20artech

我有以下代码:

#!/usr/bin/env python 
import logging 
import sys 
import copy 
 
class Wrapper: 
    def write(self, s): 
        #sys.__stdout__.write(s) 
        loggy = logging.getLogger('foobar') 
        loggy.info(s) 
 
def blah(): 
    logger = logging.getLogger('foobar') 
    logger.setLevel(logging.DEBUG) 
    streamhandle = logging.StreamHandler(sys.stdout) 
    streamhandle.setFormatter(logging.Formatter('[%(message)s]')) 
    logger.addHandler(streamhandle) 
 
    sys.stdout = Wrapper() 
    sys.stderr = Wrapper() 
 
if __name__ == '__main__': 
 
    blah() 
    logger = logging.getLogger('') 
    #print logger.handlers 
    #for handler in logger.handlers: 
    #    print handler 
 
    fooy = logging.getLogger('foobar') 
    #print fooy.handlers 
 
    sys.stdout.write('i love you') 
 
    logging.log(logging.DEBUG, 'i love you') 

此代码导致 python 进入无限递归循环,输出实际上非常酷:

[Error in sys.exitfunc: 
] 
[INFO:foobar:Error in sys.exitfunc: 
 
] 
[INFO:foobar:INFO:foobar:Error in sys.exitfunc: 
 
 
] 
[INFO:foobar:INFO:foobar:INFO:foobar:Error in sys.exitfunc: 
 
 
 
] 
[INFO:foobar:INFO:foobar:INFO:foobar:INFO:foobar:Error in sys.exitfunc: 
 
 
 
 
] 
[INFO:foobar:INFO:foobar:INFO:foobar:INFO:foobar:INFO:foobar:Error in sys.exitfunc: 

这一直呈指数增长 :) 很漂亮,但为什么会这样?

请您参考如下方法:

无限循环的发生是因为您的记录器的 StreamHandler 设置为将其日志消息写入 sys.stdout,但是 sys.stdout 是依次包装并写回刚刚向其发送写入消息的记录器。

根据您的目标,您最好让 Wrapper 实际执行输出,而不是在内部使用日志记录。像这样的东西:

class Wrapper(object): 
    def write(self, s): 
        sys.__stdout__.write(s) # sys.__stdout__ points to the original stdout, rather 
                                # than the redirected sys.stdout