2012-09-05 233 views
1

我正在將Python嵌入到C++應用程序中(使用Python C API),我想要引發的Python異常由已經在C++中設置的異常處理機制處理。這個異常處理機制將自己打印出異常,所以我不希望嵌入式Python解釋器將它打印到屏幕上。我可以設置嵌入式Python解釋器以某種方式抑制控制檯輸出嗎?禁止Python打印輸出

+0

哪些代碼正在寫入控制檯? Python代碼或C++代碼? – interjay

+0

C++代碼。我不希望Python代碼寫入控制檯。謝謝。 – duffsterlp

回答

0

你是怎麼執行代碼的?如果一個異常沒有被python直接捕獲和打印(某人已經直接在python中安裝了一個處理程序),它將被設置爲異常處理,然後可以使用C來檢查異常(請參閱參考手冊中的異常處理一節)。

如果您從C代碼調用python腳本,調用函數將返回NULL或-1(發生異常),現在您可以使用上述API讀取異常(例如PyErr_Occurred())。 ..)。

但是,如果事情是由python代碼本身完成的(如果有人在其代碼中安裝了鉤子或其他東西並直接打印它),則沒有任何變化可以輕鬆捕捉事物。也許你可以自己添加一個鉤子,調用你的代碼。這可以通過sys.excepthook(type,value,traceback)完成,一種解決方案是找到位置並將其從代碼中移除,或者查看其他方法來繞過它。

這個網站是關於它非常豐富:Python API/include files

編輯: 對於重定向stdout或stderr可以使用C-API函數:

FILE* sto = fopen("out.txt", "w+"); 
FILE* ste = fopen("outErr.txt", "w+"); 
PySys_SetObject("stdout", PyFile_FromFile(sto, "out.txt","wb", fclose)); 
PySys_SetObject("stderr", PyFile_FromFile(ste, "outErr.txt","wb", fclose)); 

調用任何其他Python代碼之前。我認爲PyFile_FromFile也可能被其他的東西取代,但我迄今爲止還沒有使用過。

4

您可以將一個Stub-Streamhandler插入到Python中的standard outstandard error通道中。

這裏的樣品(含revoicing兩個通道):

import sys 
import cStringIO 

print("Silencing stdout and stderr") 
_stdout = sys.stdout 
_stderr = sys.stderr 
sys.stdout = cStringIO.StringIO() 
sys.stderr = cStringIO.StringIO() 

print("This should not be printed out") 

sys.stdout = _stdout 
sys.stderr = _stderr 

print("Revoiced stdout and stderr") 

運行此示例應該導致下面的輸出:

Silencing stdout and stderr 
Revoiced stdout and stderr 

[增訂]

而這裏所述存儲器與發送到devnull

import os, sys 
with open(os.devnull, 'w') as devnull: 
    sys.stdout = devnull 
    sys.stderr = devnull 
    # ... here your code 
+0

將輸出重定向到像這樣的內存緩衝區會不必要地消耗內存。將它發送到'/ dev/null'(或Windows上的'NUL')可能會更好。 – martineau

+0

是的,你是對的martneau。如果你不需要緩衝區的內容,最好重定向到'os.devnull'。我已經用這個樣本更新了我的答案。 –

+0

喜歡你的更新。 ;-)可能也是有用的使它成爲一個上下文管理器,就像我在[回覆]中顯示的那樣(http://stackoverflow.com/a/3378965/355230)。 – martineau