2012-09-05 191 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