Frage

Der folgende Code ist sehr einfach, aber aus irgendeinem Grund iteriert For-Loop nicht alle Handler des Loggers. FOROOP ITRADT DIRTEN ALLE HANDLER, FÜR DIE UNTERGEBENTEN my_logger.removeHandler (Handler) in der sonstigen Klausel. Irgendeine Idee, wenn ich etwas falsch mache?

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
War es hilfreich?

Lösung

Dies ist eine klassische destruktive Iteration. Was Sie tun, ist:

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

In diesem Beispiel wird nur jedes zweite Element entfernt. Wieso den? Also, die for...in Syntax verdeckt, was tatsächlich passiert, was gleich ist wie in einem traditionellen C-Stil für die Index-Schleife:

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

Also zum ersten Mal um die Schleife i IS 0. Artikel 0 wird entfernt, und bewegte die Gegenstände 1–4 einen Ort, an dem die neuen Artikel 0–3 sind. Nächstes Mal rund um die Schleife i ist 1 Also der aktuelle Punkt 1, der ist 2, ist entfernt. Das Original 1 wurde gesprungen und bleibt in der Schleife.

Eine einfache Problemumgehung, um eine destruktive Iteration zu vermeiden, besteht darin, eine Kopie der Liste zu nehmen und die Kopie zu iterieren, während das Original geändert wird:

for handler in list(my_logger.handlers):

Verwendung filter oder Listenverständnisse sind in der Regel eine einfachere Route, wenn Sie versuchen, bestimmte Elemente aus einer Liste zu entfernen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top