我在玩Python的日志系统。我注意到在循环中从记录器对象中移除处理程序时出现了一个奇怪的行为。也就是说,我的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))
什么解释了这种行为?这是虫子还是我遗漏了什么?
如果不想全部删除(感谢the tip@CatPlusPlus):
我刚刚发现,您还可以在logging.ini文件中使用以下块执行此操作:
它基本上会停用给定记录器的所有处理程序。但这有点有限,因为你必须事先知道记录者的名字。
这不是特定于记录器的行为。永远不要对当前正在迭代的列表进行变异(插入/删除元素)。如果你需要,复印一份。在这种情况下,
testLogger.handlers = []
应该起作用。相关问题 更多 >
编程相关推荐