【发布时间】:2019-05-22 15:30:43
【问题描述】:
我想处理第三方脚本的实时输出,打印一些与模式匹配但跳过其他的行:
def thirdparty_code():
from random import choice
stuff = ['keep: important stuff', 'ignore: boring stuff']
while True:
chosen_line = choice(stuff)
print(chosen_line)
我使用redirect_stdout(将行传递给我的虚拟 IO)和扩展的StringIO(用作 IO,但也调用我的过滤函数)。但是,当我在处理函数中调用 print() 时,我得到一个 RecursionError - 这并不意外:
from io import StringIO
from contextlib import redirect_stdout
class StringIOWithCallback(StringIO):
def __init__(self, callback, **kwargs):
super().__init__(**kwargs)
self.callback = callback
def write(self, s):
super().write(s)
self.callback(s)
def filter_boring_stuff_out(line):
if line.startswith('ignore'):
return
print(line)
my_io = StringIOWithCallback(filter_boring_stuff_out)
with redirect_stdout(my_io):
thirdparty_code()
我想知道是否可以从重定向中逃脱,例如在print() 函数中指定file 参数,以便它打印到实际的标准输出。我知道我可以轻松使用标准错误流:
import sys
print(line, file=sys.stderr)
但我特别想使用标准输出。有没有一种不错的 Pythonic 方式来做到这一点?
【问题讨论】:
-
你可以通过一个函数来重定向 sys.stdout (和 std.err )来过滤东西。这通常通过日志记录来完成。尽管从外观上看,您提出的问题是您自己回答的。
-
我该怎么做?我熟悉覆盖(或临时重定向)
sys.stdout以将输出作为字符串(例如,用于单元测试)以及使用 logger 模块的自定义日志功能(并按级别过滤日志)的人的做法。但是,两者都没有像问题中那样直接解决我的“实时”过滤问题。你能详细说明一下吗? -
关于我回答了这个问题的事实 - 由于我在写这篇文章时找到了答案而发布这个特定问题是错误的还是不鼓励?我的意思是,我read the piece 和一些关于meta 的帖子,但我对这是否是一个好的问答没有强烈的感觉。到目前为止,它至少部分达到了它的目的 - 我从另一个答案中学到了一些东西。
-
如果您有答案但相信有更好的方法,那么只需将您的答案放在问题中并说出您不相信这是最好的方法的话。如果你随着时间的推移想出一个答案,那么就把它作为一个答案,但是如果你有一个答案,那么为什么要问这个问题呢?这是您在提出问题后无法在一定时间内标记答案的原因之一,人们只会提出问题,将答案放在那里,将其标记为解决方案,然后就结束了。 (即使这不是一个好的解决方案)。
-
还要重定向
stdout,所以print将被过滤,请参阅下面的答案。
标签: python python-3.x contextmanager stringio