因此,我尝试了多种解决方案,并能够减少错误消息的打印量,但是它仍然可以打印,而且我似乎无法弄清楚如何隐藏由Python调用的某些C代码打印出的此丑陋消息。我无法控制C代码,因此无法更改。

我尝试创建一个上下文管理器类来重定向我的所有输出并设置sys.tracebacklimit = 0。 trackbacklimit减小了输出的大小,但是我仍然得到以下消息显示:

Traceback (most recent call last):
AttributeError: 'SystemError' object has no attribute '_render_traceback_'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
AssertionError
Traceback (most recent call last):
AttributeError: 'SystemError' object has no attribute '_render_traceback_'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
AssertionError
Traceback (most recent call last):
AttributeError: 'SystemError' object has no attribute '_render_traceback_'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
AssertionError



该函数实际上并没有失败,只是抛出了错误的错误消息,因此我需要隐藏输出。

这是我所做的:

import sys
try:
    old = sys.tracebacklimit
    sys.tracebacklimit = 0
except:
    sys.tracebacklimit = 0
    old = 1000

def excepthook(*args, **kwargs):
    pass

old_except = sys.excepthook# = excepthook
sys.excepthook = excepthook

class suppress_stdout_stderr(object):
    '''
    A context manager for doing a "deep suppression" of stdout and stderr in
    Python, i.e. will suppress all print, even if the print originates in a
    compiled C/Fortran sub-function.
       This will not suppress raised exceptions, since exceptions are printed
    to stderr just before a script exits, and after the context manager has
    exited (at least, I think that is why it lets exceptions through).

    '''
    def __init__(self):
        # Open a pair of null files
        self.null_fds =  [os.open(os.devnull,os.O_RDWR) for x in range(2)]
        # Save the actual stdout (1) and stderr (2) file descriptors.
        self.save_fds = [os.dup(1), os.dup(2)]

    def __enter__(self):
        # Assign the null pointers to stdout and stderr.
        os.dup2(self.null_fds[0],1)
        os.dup2(self.null_fds[1],2)

    def __exit__(self, *_):
        # Re-assign the real stdout/stderr back to (1) and (2)
        os.dup2(self.save_fds[0],1)
        os.dup2(self.save_fds[1],2)
        # Close all file descriptors
        for fd in self.null_fds + self.save_fds:
            os.close(fd)



我不想为我的方法打印任何内容。

最佳答案

所以我终于想通了。我做了以下事情:

import os
from contextlib import ExitStack, redirect_stdout, redirect_stderr, suppress
from io import StringIO
err = None
with ExitStack() as stack, suppress(Exception) as s3, suppress(ValueError) as s2, suppress(SystemError) as s1:
    null_stream = StringIO()
    with redirect_stdout(null_stream) as s4:
        try:
            old = sys.tracebacklimit
            sys.tracebacklimit = 0
        except:
            sys.tracebacklimit = 0
            old = 1000
        stack.enter_context(redirect_stdout(null_stream))
        try:
            print('problem code here')
        except Exception as errmsg:
            err = errmsg
        finally:
            stack.close()
            sys.tracebacklimit = 1000
if err:
    raise err


我将所有消息推送到StringIO,并使用ExitStack()以及抑制上下文来阻止任何显示。这确实导致了一个问题,因此在try / except / finally中,我保存了任何实际错误,如果不是None,则引发该错误。

这不是一个很好的解决方案,但可以。我无法按要求访问C代码。

关于python - 如何防止错误消息显示在屏幕上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57148422/

10-11 22:22
查看更多