为什么在显式关闭stdout时会出现ValueError?

时间:2012-02-05 08:38:50

标签: python python-3.x stdout

Python新手在这里。我正在编写一个脚本,可以将一些输出转储到文件或stdout,具体取决于传递给它的参数。在解释参数时,我将open'ed文件或stdout分配给名为output_file的全局变量,无论何种类型,脚本的其余部分都可以使用该变量来编写输出选择了流。在脚本的最后,我close output_file。这适用于文件流,虽然对于stdout来说是多余的,但我使用其他编程语言的经验表明,在程序结束之前显式关闭stdout没有损害

但是,每当stdout用于输出(并随后关闭)时,我得到一个“ValueError:'对已关闭文件的I / O操作。'”。我知道这个错误不是由我调用close stdout直接产生的,而是在我的脚本返回后发生的。我的问题是:为什么会发生这种情况,有没有办法手动关闭stdout而不触发它? (我知道只有在选择了文件时才能通过有条件地关闭流来轻松解决问题,但我想知道是否/为什么这是必要的。)

非常简单的示范片段:

from sys import stdout
stdout.close()

4 个答案:

答案 0 :(得分:5)

问题是在python-3.2上有一次尝试关闭以刷新stdout而不检查它是否已关闭。

issue13444与此有关。

fixing patch之后的版本python-2.7中不应出现此问题。

答案 1 :(得分:4)

以这种方式关闭stdout后,您必须绝对确保没有任何内容会尝试将任何内容打印到stdout。如果有的话,你会得到那个例外。

我的建议是有条件地关闭output_file

if output_file != sys.stdout:
    output_file.close()

编辑以下是一个示例,其中sys.stdout在脚本的最末端关闭,但在运行时仍生成ValueError: 'I/O operation on closed file

import atexit

@atexit.register
def goodbye():
    print "You are now leaving the Python sector."

import sys
sys.stdout.close()

答案 2 :(得分:0)

关闭之前,您可以检查output_file.closed文件:

if not output_file.closed:
    output_file.close()

确保在关闭后没有对output_file的I / O调用。

答案 3 :(得分:0)

似乎有两件事要避免这个错误:reset(i)reset stdout; (ii)不要关闭stdout,关闭它被重定向到的文件。

f=open(filename, 'w')
sys.stdout = f
print("la la-la"), file = sys.stdout)
f.close()
sys.stdout = sys.__stdout__

针对此问题的各种解决方案建议复制“原始”字样。 stdout指向变量的指针,然后将stdout分配给文件(即original = stdout ... stdout = f),然后将其复制回来(stdout = original)。但是他们忽略了提到他们日常生活中的最后操作,这是浪费时间拉你的头发。

找到解决方案here