繁体   English   中英

在 Python 的 Spyder 中,将控制台打印到日志文件是不可逆的

[英]Printing the console to a log file is not reversible in Spyder for Python

我正在使用 Python 的 Spyder,有时我想将控制台打印到日志文件中(在输出很长的情况下),有时我只想在控制台上输出。 为此,我在 Python 文件中使用以下结构:

在文件的开头:

import sys
# specify if the output should be printed on a separate log file or on the console
printLogToFile = False

if printLogToFile == True:
    #Specify output file for the logs
   sys.stdout = open('C:/Users/User 1/logfile.txt', 'w')

在文件末尾:

# Close the log file if output is printed on a log file and not on the console
if printLogToFile == True:
    sys.stdout.close()
    sys.stdout = sys.__stdout__

基本上,每当我的布尔变量printLogToFile的值为 False 时,所有内容都会按原样打印在控制台上,并且每当它的值为 True 时,所有内容都会打印到日志文件中。 但是,一旦我只运行一次带有printLogToFile=True的文件, printLogToFile=True逆转了。 即使变量的值为 False,它仍然会将所有内容打印到日志文件中,而不是打印到控制台上。 更奇怪的是,对于与此文件没有任何连接的其他 Python 文件,控制台不再打印到控制台上。 解决这个问题的唯一方法是关闭Spyder并重新启动它。

您知道为什么会发生这种情况以及如何避免这种情况吗? 我会很感激每一条评论。

Spyder 中的控制台是一个IPython控制台,而不是一个普通的 Python 控制台,所以我认为 IPython 正在使用stdout做一些导致您的方法失败的事情。

sys.__stdout__文档

它还可以用于将实际文件恢复到已知的工作文件对象,以防它们被损坏的对象覆盖。 但是,执行此操作的首选方法是在替换之前显式保存先前的流,并恢复保存的对象。

换句话说,尝试:

if printLogToFile:
    prev_stdout = sys.stdout
    sys.stdout = open('C:/Users/User 1/logfile.txt', 'w')

# code that generates the output goes here

if printLogToFile:
    sys.stdout.close()
    sys.stdout = prev_stdout

作为替代方案,基于此答案此答案假设 Python >= 3.7,您可以使用contextlibwith语句有选择地捕获某些代码的输出。 这在 Spyder 4 和 5 中似乎对我有用:

from contextlib import redirect_stdout, nullcontext

if printLogToFile:
    f = open('myfile.txt', 'w')
    cm = redirect_stdout(f)
else:
    cm = nullcontext()

with cm:
    # code that generates the output goes here

如果您想执行整个 Python 脚本myscript.py并捕获它输出的所有内容, myscript.py修改脚本并从包装脚本调用它可能更容易:

# put this in the same folder as myscript.py

from contextlib import redirect_stdout

with redirect_stdout(open('myfile.txt', 'w')):
    import myscript
 

如果你想要比这更灵活的东西,可能是时候开始使用logging 了

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM