Python 2.7.2 не выполняет должным образом через обработчики регистрации

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

  •  26-10-2019
  •  | 
  •  

Вопрос

Следующий код очень прост, но по какой-то причине для петли не обращается через всех обработчиков журнала. Тем не менее, для петли выполняется через все обработчики, если мы удалим my_logger.removehandler (обработчик) в пункте еще. Есть идеи, делаю ли я что -нибудь не так?

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
Это было полезно?

Решение

Это классическая разрушительная итерация. Что вы делаете, так это:

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

В этом примере только каждый второй элемент удален. Почему? Ну for...in Синтаксис скрывает то, что на самом деле происходит, что такое же, как в традиционном цикле F-индекса в стиле C:

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

Так что впервые вокруг петли i IS 0. Пункт 0 удаляется, перемещают элементы 1–4 в одном месте, чтобы быть новыми элементами 0–3. В следующий раз по петле i является 1 Итак, текущий элемент 1, который 2, устранен. Оригинал 1 был прыгнул и остается в петле.

Простой обходной путь, чтобы избежать разрушительной итерации, - это взять копию списка и перевернуть копию, изменяя оригинал:

for handler in list(my_logger.handlers):

С использованием filter или «Понимание списка», как правило, является более простым маршрутом, когда вы пытаетесь удалить определенные элементы из списка.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top