Python PyDev:ValueError:对关闭的文件执行I/O操作

Python PyDev:ValueError:对关闭的文件执行I/O操作,python,pydev,Python,Pydev,我正在尝试将所有输出重定向到文件,并将stdout设置回默认值,以便在终端中查看更多调试日志和错误。当出现异常时,我注意到输出文件是0 KB,我使用with处理它,因此它关闭文件并允许我查看其中的内容: with open(outfile, 'w+') as o: sys.stdout = o print('First Line') print('Second Line') print('Third Line') raise Exception("Ra

我正在尝试将所有输出重定向到文件,并将
stdout
设置回默认值,以便在终端中查看更多调试日志和错误。当出现异常时,我注意到输出文件是
0 KB
,我使用
with
处理它,因此它关闭文件并允许我查看其中的内容:

with open(outfile, 'w+') as o:
    sys.stdout = o

    print('First Line')
    print('Second Line')
    print('Third Line')

    raise Exception("Raised an exception deliberately")        ........(1)

sys.stdout = sys.__stdout__                                    ........(2)
print("End")
它按预期工作,但还有一个错误:

Exception: Raised an exception deliberately
Traceback (most recent call last):
  File "F:\Python\lib\site-packages\IPython\core\interactiveshell.py", line 2963, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-1-72e8db6af18d>", line 1, in <module>
    print('PyDev console: using IPython 6.4.0\n')
ValueError: I/O operation on closed file.
同样的异常也被捕获

惊人地

finally:
    sys.stdout.close()
    sys.stdout = sys.__stdout__
解决了这个问题

抛出的错误似乎位于意外的
sys.stdout=sys.\uu stdout\uuu
行,尽管该行无法访问(由于未捕获到显式的
raise
语句)。把剩下的代码包装在
finally
中,或者在我们可以使用
时使用
try
finally
似乎是不对的,是吗


为什么会发生这种情况?

我特别有这些问题:

  • 首先,为什么异常没有写入文件中
  • 然后,为什么(2)抱怨关闭的文件?是不将
    标准输出分配给
    sys.stdout
    的命令。我不明白这与
    o

  • 我认为有两件事不好:

  • 您必须保留
    stdout
    中的内容,而不是还原
    sys.\uu stdout\uuu
    (以确保其一致性)

  • 在关闭您自己的文件之前,必须重新分配到原始文件(以避免它可能写入您关闭的文件)

  • i、 e:


    这就解决了问题,您能否深入了解关闭文件上的
    I/O操作发生的原因和方式?为什么变量赋值操作要抛出这个错误?因为您试图写入关闭后打开的文件。嗯,重新阅读我认为在您的用例中,
    sys.\uuu stdout\uuu
    已经关闭了(可能是IPython正在做的事情——我无法在常规运行中真正复制您对can的使用,因此,我假设情况就是这样)。
    finally:
        sys.stdout.close()
        sys.stdout = sys.__stdout__
    
    with open(...) as stream:
        original = sys.stdout
        sys.stdout = stream
        try:
            ...
        finally:
            sys.stdout = original