Python 2.7.2 无法正确迭代记录器的处理程序
下面的代码非常简单,但是由于某种原因,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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个经典的破坏性迭代。您正在做的是:
在此示例中,仅删除每隔一个的元素。为什么?那么
for
...in
语法掩盖了实际发生的事情,这与传统的 C 风格 for-index 循环相同:所以第一次循环 < code>i 为 0。项目 0 被删除,项目 1-4 向下移动一位,成为新项目 0-3。下一次循环时,
i
为1
,因此当前项 1(即2
)将被删除。原来的1
已被跳转并保留在循环中。避免破坏性迭代的一个简单解决方法是获取列表的副本并在更改原始列表的同时迭代副本:
当您尝试从列表中删除某些项目时,使用
过滤器
或列表推导式通常是更简单的方法。一个清单。This is a classic destructive iteration. What you are doing is:
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: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 loopi
is1
so the current item 1, which is2
, is removed. The original1
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:
Using
filter
or list comprehensions is typically a simpler route when you are trying to remove certain items from a list.