如何在引发异常时删除 Python 中的 "Traceback most recent call last"?

How to remove the "Traceback most recent call last" in Python when raising an exception?

我正在创建一个需要使用 OS 模块的 Python 程序,我想自定义报告错误消息。我正在使用 try 和 except 来完成这个:

try:
    os.mkdir(name)
except FileExistsError:
    raise FileExistsError(name + "\n" + "                        ^ The directory you specified already exists.")

但是,我想删除

Traceback (most recent call last):
  File "file.py", line 20, in <module>
    raise FileExistsError(name + "\n" + "                        ^ The directory you specified already exists.")

部分,以便每次引发异常时都不会打印引发此异常的代码。

我该怎么做?

大多数命令行程序如何做到这一点是在您与用户交互的程序顶部附近捕获异常,并以对他们有用的形式打印出来:

def makedir(name):
    try:
        os.mkdir(name)
    except FileExistsError:
        raise FileExistsError(
            name + "\n" + "^ The directory you specified already exists."
        )


def main():
    try:
        makedir("/tmp")
    except FileExistsError as e:
        print("OOOPS", e)
        return

如果您在顶部捕获过于广泛的异常 class,您将损害您自己的调试能力以及您的用户为您提供准确错误消息的能力,因此您应该准确。事实上,您可能想像这样发明自己的异常 classes:

class MyAppExceptions(Exception):
    pass


class MyAppFileExists(MyAppExceptions):
    pass


def makedir(name):
    try:
        os.mkdir(name)
    except FileExistsError:
        raise MyAppFileExists(
            name + "\n" + "^ The directory you specified already exists."
        )


def main():
    try:
        makedir("/tmp")
    except MyAppFileExists as e:
        print("OOOPS", e)
        return

然后,如果您的程序由于您没有预料到的原因而出现 FileExistsError,您仍然会获得可用于调试的异常回溯。

如果你想忽略完整回溯,有一个简单的方法:

try:
    ...
except FileExistsError as e:
    raise MyAppFileExists('message').with_traceback(None) from None

如果你只想删除最后一部分,那就有点难了:

try:
    ...
except FileExistsError:
    try:
        raise MyAppFileExists('message')
    except MyAppFileExists as e:
        tb=e.__traceback__
        next_tb=tb
        while next_tb.tb_next.tb_next is not None:
            next_tb=next_tb.tb_next
        next_tb.tb_next=None
        raise e.with_traceback(tb) from None 

from None表示Python不应打印During handling of the above exception, another exception occurred:。如果您希望发生这种情况,只需删除 from None 部分