如何在例外情况下将默认消息更改为自定义消息?

时间:2019-12-11 20:25:57

标签: python python-3.x exception

这可能是一个愚蠢的问题,所以我对这些问题进行了一些研究:

How do I raise the same Exception with a custom message in Python?
Proper way to declare custom exceptions in modern Python?

但是这些都不符合我为CLI脚本所做的尝试,即:

1。)如果引发了某个Exception,我想用经过定制的消息而不是默认消息重新引发相同的Exception
2.)我不是希望重新定义自定义Exception类型,与Exception相同。
3.)我不是正在寻找print控制台文本。我实际上要raise Exception是因为我需要退出代码尽可能接近原始Exception的位置,因为另一个进程依赖此代码。
4.)我希望误差尽可能的短,直而准确。不需要完全追溯。

例如,这些是我尝试过的:

尝试1:

def func():    
    try:
        1/0
    except ZeroDivisionError:
        raise ZeroDivisionError("Don't do that you numbnut!")

结果1:

Traceback (most recent call last):
  File "c:\Users\Dude\test.py", line 3, in <module>
    1/0
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\Users\Dude\test.py", line 5, in <module>
    raise ZeroDivisionError("Don't do that you numbnut!")
ZeroDivisionError: Don't do that you numbnut!

[Done] exited with code=1 in 2.454 seconds

这符合我的#1、2和3的目标,但是回溯时间太长了……我根本不需要原始的Exception,只需要自定义消息即可。

尝试2:

def catch():
    try:
        1/0
        return None
    except ZeroDivisionError:
        return ZeroDivisionError("Don't do that you numbnut!")

error = catch()
if error:
    raise error

结果2:

Traceback (most recent call last):
  File "c:\Users\Dude\test.py", line 10, in <module>
    raise error
ZeroDivisionError: Don't do that you numbnut!

[Done] exited with code=1 in 2.458 seconds

这使我非常接近我想要的并且正在做的事情,但是感觉很不切实际,pylint抱怨raise error这一行:

  

在仅允许类或实例的情况下提高NoneType   pylint(raising-bad-type)

我在链接的问题中也尝试了这些方法,但是它们也不能满足我的所有要求。为了简洁起见,我没有在这里包括我的尝试。

因此,我的问题是:是否有更好,更明显的方法来捕获Exception并使用我只是想念的自定义消息来重新引发它?

3 个答案:

答案 0 :(得分:2)

从一开始,这一切对我来说似乎都是很神奇的-但是,如果您确实要这么做,为什么在第一个示例中不提出from None以免获得较大的回溯。

def func():
    try:
        1/0
    except ZeroDivisionError:
        raise ZeroDivisionError("Don't do that you numbnut!") from None


func()

给予

Traceback (most recent call last):
  File "/Users/dmodesitt/Dev/the.py", line 9, in <module>
    func()
  File "/Users/dmodesitt/Dev/the.py", line 6, in func
    raise ZeroDivisionError("Don't do that you numbnut!") from None
ZeroDivisionError: Don't do that you numbnut!

答案 1 :(得分:2)

此功能称为“链接的异常”,是在Python 3中添加的。

此街区

try:
    1 / 0
except ZeroDivisionError:
    raise ZeroDivisionError("Don't do that you numbnut!")

>>>>

Traceback (most recent call last):
  File "test123.py", line 2, in <module>
    1 / 0
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test123.py", line 4, in <module>
    raise ZeroDivisionError("Don't do that you numbnut!")
ZeroDivisionError: Don't do that you numbnut!

类似于

try:
    1 / 0
except ZeroDivisionError as e:
    raise ZeroDivisionError("Don't do that you numbnut!") from e
=>>>>>>>>>
raceback (most recent call last):
  File "test123.py", line 2, in <module>
    1 / 0
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "test123.py", line 4, in <module>
    raise ZeroDivisionError("Don't do that you numbnut!") from e
ZeroDivisionError: Don't do that you numbnut!

但是您可以使用from None语句禁用异常链接。

try:
    1 / 0
except ZeroDivisionError:
    raise ZeroDivisionError("Don't do that you numbnut!") from None
=>>>>>>>>
Traceback (most recent call last):
  File "test123.py", line 4, in <module>
    raise ZeroDivisionError("Don't do that you numbnut!") from None
ZeroDivisionError: Don't do that you numbnut!

有关该功能的更多信息,位于https://www.python.org/dev/peps/pep-3134/

答案 2 :(得分:0)

我还可以使用exit(...)复制与我想要的内容非常相似的内容,但再次感到有点怪诞:

def func():
    try:
        1/0
    except ZeroDivisionError as err:
        exit(f"{err.__class__.__name__}: Don't do that you numbnut!")

结果:

ZeroDivisionError: Don't do that you numbnut!

[Done] exited with code=1 in 3.433 seconds

就我的脚本而言,我认为这可能是最简单的解决方案。但是从更广泛的角度来看,我相信其他答案会更好。