在Python中关闭流的不同方法

1 投票
2 回答
2809 浏览
提问于 2025-04-18 17:29

这两个代码块有什么区别呢?

os.close(sys.stdout.fileno())

sys.stdout.close()

我看过文档,感觉它们的功能差不多,但有时候我用第一个代码块时会遇到“坏的文件描述符”错误。

2 个回答

2

你可能不想选择前一种做法。这样做会关闭与 sys.stdout 相关的文件描述符。之后,当 sys.stdout 被释放(比如你重新赋值给它)时,你会遇到错误,因为从 Python 的角度来看,stdout 的文件描述符已经突然消失了。

更糟糕的是,如果你在这期间打开了其他文件,文件描述符可能会被重新使用,这样 sys.stdout 就会高兴地关闭那个文件,导致更多麻烦。

总是使用后者。这样更安全、更通用,也更合理。

5

请阅读这篇文章:sys.stdout 和 os.close

在Python中,文件对象是建立在C语言标准输入输出流之上的一种高级抽象。这些C语言的标准流又是在一些低级的C文件描述符之上构建的中级抽象。

当你通过Python内置的open函数创建大多数文件对象时,调用close方法会将这个Python文件对象标记为已关闭,同时也会关闭底层的C流。在f对象被垃圾回收时,这个关闭操作也会自动发生。

但是,stdin、stdout和stderr在Python中是被特殊对待的,因为C语言也赋予了它们特殊的地位。调用sys.stdout.close会将Python层的文件对象标记为已关闭,但并不会关闭相关的C流。

如果你想关闭这三者中的一个的底层C流,首先要确保这确实是你想要做的事情(例如,这可能会让一些扩展模块在进行输入输出时感到困惑)。如果确定要这样做,可以使用os.close:

os.close(0)   # close C's stdin stream
os.close(1)   # close C's stdout stream
os.close(2)   # close C's stderr stream

撰写回答