【发布时间】:2011-11-21 00:25:23
【问题描述】:
我正在使用 Python 的日志记录系统。在循环中从 Logger 对象中删除处理程序时,我注意到了一种奇怪的行为。也就是说,我的 for 循环删除了除一个处理程序之外的所有处理程序。对.removeHandler 的额外调用会顺利移除最后一个处理程序。调用期间不会发出错误消息。
这是测试代码:
import logging
import sys
logging.basicConfig()
dbg = logging.getLogger('dbg')
dbg.setLevel(logging.DEBUG)
testLogger = logging.getLogger('mylogger')
sh = logging.StreamHandler(sys.stdout)
fh = logging.FileHandler('mylogfile.log')
dbg.debug('before adding handlers: %d handlers'%len(testLogger.handlers))
testLogger.addHandler(fh)
testLogger.addHandler(sh)
dbg.debug('before removing. %d handlers: %s'%(len(testLogger.handlers),
str(testLogger.handlers)))
for h in testLogger.handlers:
dbg.debug('removing handler %s'%str(h))
testLogger.removeHandler(h)
dbg.debug('%d more to go'%len(testLogger.handlers))
#HERE I EXPECT THAT NO HANDLER WILL REMAIN
dbg.debug('after removing: %d handlers: %s'%(len(testLogger.handlers),
str(testLogger.handlers)))
if len(testLogger.handlers) > 0:
#Why is this happening?
testLogger.removeHandler(testLogger.handlers[0])
dbg.debug('after manually removing the last handler: %d handlers'%len(testLogger.handlers))
我希望在循环结束时,testLogger 对象中不会保留任何处理程序,但是
最后一次调用.removeHandler 显然失败了,从下面的输出可以看出。尽管如此
对该函数的额外调用将按预期删除处理程序。这是输出:
DEBUG:dbg:before adding handlers: 0 handlers
DEBUG:dbg:before removing. 2 handlers: [<logging.FileHandler instance at 0x021263F0>, <logging.StreamHandler instance at 0x021262B0>]
DEBUG:dbg:removing handler <logging.FileHandler instance at 0x021263F0>
DEBUG:dbg:1 more to go
DEBUG:dbg:after removing: 1 handlers: [<logging.StreamHandler instance at 0x021262B0>]
DEBUG:dbg:after manually removing the last handler: 0 handlers
更有趣的是,如果我用下面的循环替换原来的循环,循环
按预期工作,循环结束时testLogger 对象中没有任何处理程序。
这是修改后的循环:
while len(testLogger.handlers) > 0:
h = testLogger.handlers[0]
dbg.debug('removing handler %s'%str(h))
testLogger.removeHandler(h)
dbg.debug('%d more to go'%len(testLogger.handlers))
什么解释了这种行为?这是一个错误还是我错过了什么?
【问题讨论】:
-
for h in list(testLogger.handlers)