簡體   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