Estoy jugando con el sistema de registro de Python. He notado un comportamiento extraño al eliminar manejadores de un objeto Logger en un bucle. A saber, mi bucle for elimina todos los controladores excepto uno. Llamada adicional al .removeHandler
elimina el último controlador sin problemas. No se emiten mensajes de error durante las llamadas.Eliminando manejadores de los registradores de inicio de sesión de python
Este es el código de prueba:
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))
espero que al final del bucle no hay controladores permanecerán en el objeto testLogger
, sin embargo la última llamada a .removeHandler
aparentemente falla, como puede verse a partir el resultado a continuación. Sin embargo, llamada adicional a esta función elimina el controlador como se esperaba. Aquí está la salida:
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
Más interesante, si reemplazo del bucle original con el siguiente, el bucle funciona como se espera y no hay controladores permanecen en el objeto testLogger
al final del bucle. Aquí es el bucle modificado:
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))
¿Cómo se explica este comportamiento? ¿Es esto un error o me estoy perdiendo algo?
'por h en la lista (testLogger.handlers)' – sherpya