在 Python 中使用 with 语句时,将 stderr 和 stdout 重定向到文件不会写入错误
Redirecting stderr and stdout to a file does not write errors when using with statements in Python
我有一个程序可以将输出和错误重定向到一个日志文件,这样我就可以在它自动运行时查看它。它工作正常,直到我从使用 open()
和 close()
方法切换到使用 with
语句。
我的原文是:
import sys
log = open("log.txt", "w", encoding="utf-8")
sys.stdout = sys.stderr = log
print("hello world")
print(1 / 0)
print("goodbye world")
log.close()
它输出了我预期的结果:
hello world
Traceback (most recent call last):
File "testing.py", line 5, in <module>
print(1 / 0)
ZeroDivisionError: division by zero
但是当我把它改成:
import sys
with open("log.txt", "w", encoding="utf-8") as log:
sys.stdout = sys.stderr = log
print("hello world")
print(1 / 0)
print("goodbye world")
文件只显示:
hello world
我不熟悉这两种方法之间的区别(除了第二种方法更容易阅读)所以我的问题是:为什么 with
语句无法记录错误并且有没有办法在保留 with
语句的同时记录错误?
发生这种情况是因为 with
语句由于发生异常而在写入错误输出之前关闭了资源。
看看 docs.
The following code:
with EXPRESSION as TARGET:
SUITE
is semantically equivalent to:
manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not exit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
exit(manager, None, None, None)
第一种情况处理异常的原因是因为资源在python退出时关闭,而不是因为关闭语句。
我有一个程序可以将输出和错误重定向到一个日志文件,这样我就可以在它自动运行时查看它。它工作正常,直到我从使用 open()
和 close()
方法切换到使用 with
语句。
我的原文是:
import sys
log = open("log.txt", "w", encoding="utf-8")
sys.stdout = sys.stderr = log
print("hello world")
print(1 / 0)
print("goodbye world")
log.close()
它输出了我预期的结果:
hello world
Traceback (most recent call last):
File "testing.py", line 5, in <module>
print(1 / 0)
ZeroDivisionError: division by zero
但是当我把它改成:
import sys
with open("log.txt", "w", encoding="utf-8") as log:
sys.stdout = sys.stderr = log
print("hello world")
print(1 / 0)
print("goodbye world")
文件只显示:
hello world
我不熟悉这两种方法之间的区别(除了第二种方法更容易阅读)所以我的问题是:为什么 with
语句无法记录错误并且有没有办法在保留 with
语句的同时记录错误?
发生这种情况是因为 with
语句由于发生异常而在写入错误输出之前关闭了资源。
看看 docs.
The following code:
with EXPRESSION as TARGET:
SUITE
is semantically equivalent to:
manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not exit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
exit(manager, None, None, None)
第一种情况处理异常的原因是因为资源在python退出时关闭,而不是因为关闭语句。