【问题标题】:Suppress Python printout禁止 Python 打印输出
【发布时间】:2012-09-05 14:12:53
【问题描述】:

我正在将 Python 嵌入到 C++ 应用程序中(使用 Python C API),并且我希望抛出的 Python 异常由已在 C++ 中设置的异常处理程序机制进行处理。这种异常处理机制将打印出异常本身,因此我不希望嵌入式 Python 解释器将其打印到屏幕上。我可以设置嵌入式 Python 解释器以某种方式抑制控制台输出吗?

【问题讨论】:

  • 哪个代码正在写入控制台? Python 代码还是 C++ 代码?
  • C++ 代码。我不希望将 Python 代码写入控制台。谢谢。

标签: c++ python


【解决方案1】:

您可以将 Stub-Streamhandler 插入 python 中的 standard outstandard error 通道。

这里是一个示例(包括取消两个通道):

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

【讨论】:

  • 像这样将输出重定向到内存缓冲区会不必要地消耗内存。最好将其发送到/dev/null(或Windows 上的NUL)。
  • 是的,你说得对。如果您不需要缓冲区的内容,最好将两者都重定向到os.devnull。我已经用这个示例更新了我的回答者。
  • 喜欢你的更新。 ;-) 将它作为一个上下文管理器也可能有用,就像我在answer 中展示的那样。
  • 问卷要求一种在 C++ 中而不是在 Python 控制台上实现此功能的方法(请参阅问题的最后第二条评论)。大体的方式是他想做的,但是这里缺少了CApi的实现。
【解决方案2】:

您是如何执行代码的?如果异常没有被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 也可能被其他东西取代,但到目前为止我还没有使用过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-30
    • 1970-01-01
    • 2012-02-09
    • 2015-08-27
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多