重定向 sys.stdout 前必须保存 original_stdout,使用行缓冲(buffering=1),追加模式('a')写日志,注意其不影响 logging 模块,需手动 flush 和 close 文件,多线程下不安全。

用 sys.stdout 重定向前必须先保存原始句柄
直接赋值 sys.stdout = open(...) 后,一旦出错或想恢复打印到控制台,就找不回原来的输出目标了。Python 不会自动帮你存一份备份。
- 务必在重定向前用
original_stdout = sys.stdout保存原始对象 - 文件对象要带
buffering=1(行缓冲)或line_buffering=True,否则print()可能不实时写入,尤其配合time.sleep()或长循环时容易“卡住”没日志 - 别用
open('log.txt', 'w')简单覆盖——如果程序中途崩溃,之前日志全丢;改用'a'模式追加更稳妥
print() 和 logging 混用时重定向会失效
sys.stdout 重定向只影响走 print()、input()、未指定 file= 的 print() 输出,对 logging 模块完全没作用。很多人以为“重定向 stdout 就等于所有输出进文件”,结果发现日志没进去。
-
logging.info('hello')默认输出到sys.stderr,和stdout是两个独立通道 - 如果真要用
logging写同一文件,得显式配置FileHandler,而不是依赖重定向 - 混合使用时,建议统一用
logging,避免重定向 + 日志 handler 冲突导致部分输出丢失
进程退出前必须手动 close() 重定向的文件
靠 sys.stdout = original_stdout 切回去不等于关文件。Python 解释器退出时不一定自动 flush + close 你 open 的日志文件,尤其 Windows 下可能锁住文件、内容写不全。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 推荐用
with open(...) as f:包裹重定向逻辑,确保离开作用域时自动关闭 - 如果必须全局重定向(比如整个脚本生命周期),退出前要显式调用
f.close(),并在try/finally里做 - 漏掉
flush()也可能导致最后一段输出滞留在缓冲区——f.flush()比f.close()更轻量,适合循环中定期刷盘
多线程环境下 sys.stdout 重定向不安全
sys.stdout 是全局对象,多个线程同时 print 会抢同一个文件对象,轻则日志错行、字符粘连,重则抛 ValueError: I/O operation on closed file。
立即学习“Python免费学习笔记(深入)”;
- 不要在线程里直接改
sys.stdout——每个线程看到的是同一个引用 - 想让各线程写不同日志?用
threading.local()配合独立open()文件句柄,或直接用logging的线程安全机制 - 如果只是主脚本跑完一次性导出,且无并发,那单线程重定向没问题;但只要涉及
threading或multiprocessing,就得换方案
sys.stdout 看似简单,真正落地时最常栽在缓冲没刷、文件没关、多线程抢写、以及和 logging 误混这四件事上。


















