Python标准输入输出重定向本质是替换sys.stdin、sys.stdout、sys.stderr三个文件对象,使input()、print()等函数读写指定目标而非终端;需确保新对象为实现read()/write()/flush()的类文件对象。

Python 的标准输入输出重定向,本质是替换 sys.stdin、sys.stdout 和 sys.stderr 这三个文件对象的引用,让 input()、print() 等内置函数读写到你指定的目标(如文件、字符串缓冲区或自定义类),而不是默认的终端。
重定向的核心:替换 sys 模块的文件对象
Python 启动时,sys.stdin 默认绑定到操作系统分配的文件描述符 0(标准输入),sys.stdout 绑定到描述符 1,sys.stderr 绑定到描述符 2。这些对象必须是“类文件对象”(file-like object),即实现了 read()、write()、flush() 等必要方法的对象。
- 重定向输入:赋值
sys.stdin = open('input.txt')或io.StringIO('hello\nworld') - 重定向输出:赋值
sys.stdout = open('output.txt', 'w')或io.StringIO() - 重定向错误:同理,修改
sys.stderr即可
print() 和 input() 为什么受重定向影响
print() 默认向 sys.stdout 写入,input() 默认从 sys.stdin 读取。它们内部不直接操作系统描述符,而是调用当前 sys.stdout.write() 和 sys.stdin.readline()。因此只要替换了 sys 中的对应对象,行为就自动改变。
- 注意:
print(..., file=xxx)可绕过sys.stdout,直接写入指定文件对象 -
input(prompt)的 prompt 字符串仍走sys.stdout,所以重定向后 prompt 也会进文件
安全重定向的常用做法
直接覆盖 sys.stdin 等存在风险(比如忘记恢复、多线程冲突)。推荐用上下文管理器封装:
立即学习“Python免费学习笔记(深入)”;
- 使用
contextlib.redirect_stdout()和redirect_stderr()、redirect_stdin()(Python 3.7+) - 手动保存原对象再恢复:
old_in, sys.stdin = sys.stdin, new_in,退出前再赋值回去 - 对字符串捕获,优先用
io.StringIO而非临时文件,避免磁盘 I/O 和清理问题
底层与操作系统的关联
虽然 Python 层重定向的是高层文件对象,但最终仍依赖操作系统文件描述符。例如 open('file.txt') 返回的文件对象底层持有 OS 文件描述符;而 sys.stdin 在交互模式下通常指向 /dev/tty 或管道。调用 os.dup2() 可在更低层重定向描述符(如 C 扩展中常见),但纯 Python 一般不需要触及这一层。
理解这点有助于调试:如果重定向后子进程输出异常,可能是因为子进程继承了被修改的描述符,需显式控制 subprocess.Popen(..., stdin/stdout/stderr=...)。










