我可以将标准输出重定向到某种字符串缓冲区吗?
我正在使用 python 的 ftplib 编写一个小型 FTP 客户端,但包中的某些函数不返回字符串输出,而是打印到 stdout。 我想将 stdout
重定向到一个我能够读取输出的对象。
我知道 stdout 可以通过以下方式重定向到任何常规文件:
stdout = open("file", "a")
但我更喜欢不使用本地驱动器的方法。
我正在寻找类似 Java 中的 BufferedReader 之类的东西,可用于将缓冲区包装到流中。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这是对此的另一种看法。
contextlib.redirect_stdout
与io.StringIO()
作为 记录很棒,但对于日常使用来说仍然有点冗长。 以下是如何通过子类化 contextlib.redirect_stdout 使其成为单行代码:由于 __enter__ 返回 self,因此在 with 块退出后可以使用上下文管理器对象。 此外,由于 __repr__ 方法,上下文管理器对象的字符串表示实际上是 stdout。 所以现在你有,
Here's another take on this.
contextlib.redirect_stdout
withio.StringIO()
as documented is great, but it's still a bit verbose for every day use. Here's how to make it a one-liner by subclassingcontextlib.redirect_stdout
:Since __enter__ returns self, you have the context manager object available after the with block exits. Moreover, thanks to the __repr__ method, the string representation of the context manager object is, in fact, stdout. So now you have,
使用
pipe()
并写入适当的文件描述符。https://docs.python.org/library/os.html#文件描述符操作
Use
pipe()
and write to the appropriate file descriptor.https://docs.python.org/library/os.html#file-descriptor-operations
在Python3.6中,
StringIO
和cStringIO
模块已经消失,你应该使用io.StringIO
代替。所以你应该像第一个一样这样做回答:In Python3.6, the
StringIO
andcStringIO
modules are gone, you should useio.StringIO
instead.So you should do this like the first answer:即使出现异常,此方法也会恢复 sys.stdout。 它还会在异常发生之前获取任何输出。
使用
io.BytesIO()< 在 Python 2.7.10 中进行测试/code>
使用
io 在 Python 3.6.4 中进行测试.StringIO()
Bob,如果您觉得修改/扩展的代码实验中的任何内容可能会在任何意义上变得有趣,则添加一个案例,否则随意删除它
This method restores sys.stdout even if there's an exception. It also gets any output before the exception.
Tested in Python 2.7.10 using
io.BytesIO()
Tested in Python 3.6.4 using
io.StringIO()
Bob, added for a case if you feel anything from the modified / extended code experimentation might get interesting in any sense, otherwise feel free to delete it
从 Python 2.6 开始,您可以使用任何实现
io.TextIOBase
API 作为替代品。此解决方案还允许您在 Python 3 中使用 sys.stdout.buffer.write() 来将(已)编码的字节字符串写入标准输出(请参阅 Python 3 中的 stdout)。
那么使用 io.StringIO 就不起作用了,因为 sys.stdout.buffer 和 sys.stdout.encoding 都不可用。
使用 io.TextIOWrapper 的解决方案:
此解决方案适用于 Python 2 >= 2.6 和 Python 3。
请注意,新的 sys.stdout.write() 只接受 unicode字符串和 sys.stdout.buffer.write() 只接受字节字符串。
无需更改即可在 Python 2 和 3 上运行的代码通常会使用 sys.stdout.buffer。
因此,要让 sys.stdout.write() 接受 unicode 和字节字符串,您可以使用这个 io.TextIOWrapper 子类:
您不必设置编码缓冲区的
sys.stdout.encoding
,但这在使用此方法测试/比较脚本输出时很有帮助。Starting with Python 2.6 you can use anything implementing the
io.TextIOBase
API as a replacement.This solution also enables you to use
sys.stdout.buffer.write()
in Python 3 to write (already) encoded byte strings to standard output (see stdout in Python 3).Using
io.StringIO
wouldn't work then, because neithersys.stdout.buffer
norsys.stdout.encoding
would be available.A solution using
io.TextIOWrapper
:This solution works for Python 2 >= 2.6 and Python 3.
Please note that the new
sys.stdout.write()
only accepts unicode strings andsys.stdout.buffer.write()
only accepts byte strings.Code that is built to run on Python 2 and 3 without changes often makes use of
sys.stdout.buffer
.So to have
sys.stdout.write()
accept both unicode and byte strings, you can instead use thisio.TextIOWrapper
subclass:You don't have to set the encoding of the buffer the
sys.stdout.encoding
, but this helps when using this method for testing/comparing script output.python3 的上下文管理器:
使用如下:
A context manager for python3:
use like this:
只是添加到上面 Ned 的答案中:您可以使用它将输出重定向到任何实现 write(str) 方法的对象。
这可以很好地用于在 GUI 应用程序中“捕获”stdout 输出。
这是 PyQt 中的一个愚蠢的例子:
Just to add to Ned's answer above: you can use this to redirect output to any object that implements a write(str) method.
This can be used to good effect to "catch" stdout output in a GUI application.
Here's a silly example in PyQt:
有一个
contextlib.redirect_stdout()
函数< Python 3.4+ 中的 /a>:这是一个代码示例,展示了如何在较旧的 Python 版本上实现它。
There is a
contextlib.redirect_stdout()
function in Python 3.4+:Here's a code example that shows how to implement it on older Python versions.