在Python實現print標准輸出sys.stdout、stderr重定向及捕獲的簡單辦法


Python中的標准輸出和錯誤輸出由sys模塊的stdout、stderr對象負責,所有print語句以及相關的錯誤信息輸出如果要重定向,只需要創建一個類似文件IO的類並將該類的實例替換sys模塊的stdout、stderr對象即可。

具體來說,分如下幾步完成:

  1. 備份標准輸出sys.stdout、stderr對象,以便恢復或做其他處理;

  2. 構建一個支持類似文件io的類
    Python判斷對象是否支持文件IO,是個典型的鴨子類型處理方式,就是看對象是否實現了讀寫方法,由於標准輸出無需讀只需寫,因此只要實現了write方法即可,在對應write方法對捕獲輸出信息進行處理,如輸出到特定文件或圖形化窗口

  3. 使用該類似文件io的類創建一個對象,將其賦值給sys.stdout。

案例:

import sys
class myStdout():
    def __init__(self):
        self.stdoutbak = sys.stdout
        self.stderrbak = sys.stderr
        sys.stdout = self
        sys.stderr = self
        
    def write(self,info):
       #info信息即標准輸出sys.stdout和sys.stderr接收到的輸出信息
       str = info.rstrip("\r\n")
       if len(str):self.processInfo(str)  #對輸出信息進行處理的方法
    
    def processInfo(self,info):
        self.stdoutbak.write("標准輸出接收到消息:"+info+"\n") #可以將信息再輸出到原有標准輸出,在定位問題時比較有用
	
    def restoreStd(self):
        print("准備恢復標准輸出")
        sys.stdout = self.stdoutbak 
        sys.stderr = self.stderrbak 
        print("恢復標准輸出完成")

    def __del__(self):
       self.restoreStd()

print("主程序開始運行,創建標准輸出替代對象....")
mystd = myStdout()
print("標准輸出替代對象創建完成,准備銷毀該替代對象")
#mystd.restoreStd()
del mystd
print("主程序結束")

運行截圖:

在這里插入圖片描述
可以看到,由於上述代碼恢復標准輸出是從析構方法調用的,由於Python銷毀對象的內在處理機制導致析構方法不會在執行del后即執行,且析構方法執行存在不可控因素,導致主程序退出后析構方法未調用,直到執行完成后再次在輸出界面按回車鍵才輸出信息,並且這種析構處理過程帶有一定的隨機性。因此最好顯示的調用恢復標准輸出的restoreStd方法,且不一定要執行del語句,這樣更可控。
下面是調整的主程序代碼:

print("主程序開始運行,創建標准輸出替代對象....")
mystd = myStdout()
print("標准輸出替代對象創建完成,准備銷毀該替代對象")
mystd.restoreStd()
#del mystd
print("主程序結束")

執行后結果如下:
在這里插入圖片描述
從上述過程可以明顯看到標准輸出重定向捕獲成功了。

老猿Python,跟老猿學Python!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM