Python 2.7.2 无法正确迭代记录器的处理程序

发布于 2024-12-10 18:26:43 字数 1077 浏览 0 评论 0原文

下面的代码非常简单,但是由于某种原因,for循环并没有迭代记录器的所有处理程序。但是,如果我们删除 else 子句中的 my_logger.removeHandler( handler ) ,for-loop 会迭代所有处理程序。知道我是否做错了什么吗?

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

the following code is very simple, but for some reason, for-loop does not iterate through all handlers of the logger. however, for-loop does iterate through all handlers if we remove my_logger.removeHandler( handler ) in the else clause. any idea if I'm doing anything wrong?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

盗梦空间 2024-12-17 18:26:43

这是一个经典的破坏性迭代。您正在做的是:

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

在此示例中,仅删除每隔一个的元素。为什么?那么 for...in 语法掩盖了实际发生的事情,这与传统的 C 风格 for-index 循环相同:

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

所以第一次循环 < code>i 为 0。项目 0 被删除,项目 1-4 向下移动一位,成为新项目 0-3。下一次循环时,i1,因此当前项 1(即 2)将被删除。原来的 1 已被跳转并保留在循环中。

避免破坏性迭代的一个简单解决方法是获取列表的副本并在更改原始列表的同时迭代副本:

for handler in list(my_logger.handlers):

当您尝试从列表中删除某些项目时,使用过滤器或列表推导式通常是更简单的方法。一个清单。

This is a classic destructive iteration. What you are doing is:

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

In this example only every second element is removed. Why? Well the for...in syntax obscures what's actually happening, which is the same as in a traditional C-style for-index loop:

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

So first time round the loop i is 0. Item 0 gets removed, moving items 1–4 down one place to be the new items 0–3. Next time round the loop i is 1 so the current item 1, which is 2, is removed. The original 1 has been jumped and remains in the loop.

A simple workaround to avoid destructive iteration is to take a copy of the list and iterate the copy whilst changing the original:

for handler in list(my_logger.handlers):

Using filter or list comprehensions is typically a simpler route when you are trying to remove certain items from a list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文