Я играю с системой регистрации Python. Я заметил странное поведение при удалении обработчиков из объекта Logger в цикле. А именно, цикл for 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))
Чем объясняется это поведение? Является ли это ошибкой или я что-то упускаю?