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