主要观点:在 Python 中,执行代码时将 sys.stdout 重定向到流或文件是常见任务,但有时并不像预期那么简单,特别是当 Python 进程中的 C 代码也要按意愿重定向 stdout 时,这涉及文件描述符、缓冲区和系统调用等。
关键信息:
- 纯 Python 中,使用 contextlib.redirect_stdout 或自定义的 stdout_redirector 可轻松重定向 Python 代码的输出。
- 重定向 C 级流时,直接调用 C 库的 puts 函数等输出会绕过重定向器,原因是 Python 和 C 代码使用不同的文件对象,需通过操作文件描述符来深层替换。
- 改进的 stdout_redirector 通过文件描述符复制来重定向 C 代码输出,需注意输出顺序、echo 输出重定向原因、使用 BytesIO 及代码适用于 Python 3 等细节。
- 子进程 stdout 重定向可使用 subprocess 模块的 Popen 类和 communicate 方法,或更简单的 check_output 方法。
重要细节: - Python 3.4 有内置的 contextlib.redirect_stdout 工具。
- 上下文管理器 with 语句用于自动管理重定向和清理。
- 文件描述符是进程内管理的文件抽象,标准输出是 Unix 上的文件描述符 1。
- C 运行时库提供文件描述符的抽象 - 流,FILE 结构用于缓冲和操作文件。
- Python 对底层文件描述符有自己的抽象 - 文件对象,Python 3 中还有 io.TextIOWrapper 进行编码。
- dup 和 dup2 函数用于操作文件描述符。
- subprocess 模块的 Popen 类可用于管理子进程的 stdout。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。