Python 2.7.2 n'itérer pas correctement par les gestionnaires de l'enregistreur

StackOverflow https://stackoverflow.com/questions/7812263

  •  26-10-2019
  •  | 
  •  

Question

le code suivant est très simple, mais pour une raison quelconque, pour la boucle ne itérer par tous les gestionnaires de l'enregistreur. Cependant, pour la boucle itérer fait par tous les gestionnaires si nous enlevons my_logger.removeHandler (gestionnaire) dans la clause d'autre. une idée si je fais mal de quoi que ce soit?

import logging
import sys

stdf = logging.Formatter( "%(message)s" )
filef = logging.Formatter( "%(message)s" )
my_logger = logging.getLogger( "file std logger" )
stdh = logging.StreamHandler( sys.stdout )
stdh.setFormatter( stdf )
my_logger.addHandler( stdh )
fileh = logging.FileHandler( "run.log", mode = 'w', encoding = "utf-16-le", delay = True )
fileh.setLevel( logging.DEBUG )
fileh.setFormatter( filef )
my_logger.addHandler( fileh )

my_logger.info("wow1")
my_logger.info("test string1")
my_logger.info("wow2")
my_logger.info("test string2")
my_logger.info("wow3")
my_logger.info("test string3")

for handler in my_logger.handlers:
    print(handler)
    if handler.__class__.__name__ == "FileHandler":
        handler.flush()
        handler.close()
        my_logger.removeHandler( handler )
    else:
        handler.flush()
        my_logger.removeHandler( handler )

my_logger.handlers
Était-ce utile?

La solution

Ceci est une itération destructrice classique. Ce que vous faites est:

>>> l= [0, 1, 2, 3, 4]
>>> for n in l:
...     l.remove(n)
... 
>>> l
[1, 3]

Dans cet exemple, que chaque deuxième élément est retiré. Pourquoi? Eh bien, le for ... in syntaxe obscurcit ce qui se passe réellement, ce qui est le même que dans un style traditionnel C-boucle pour-index:

>>> l= [0, 1, 2, 3, 4]
>>> i= 0
>>> while i<len(l):
...     del l[i]
...     i+= 1
...
>>> l
[1, 3]

première fois autour de la i boucle est 0. 0 article est alors retiré, déplacer des éléments 1-4 vers le bas un endroit pour être les nouveaux éléments 0-3. La prochaine fois autour de la boucle est i 1 si l'élément courant 1, qui est 2, est supprimée. Le 1 original a été sauté et reste dans la boucle.

Une solution simple pour éviter l'itération destructive est de prendre une copie de la liste et itérer la copie tout en changeant l'original:

for handler in list(my_logger.handlers):

compréhensions filter ou liste est généralement une route plus simple lorsque vous essayez de supprimer certains éléments d'une liste.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top