为什么 "raise Exception" 没有结果?

Why "raise Exception" result in nothing?

如果我有一个 1/0 的表达式,显然,它会出错:

try:
    1/0
except ZeroDivisionError as err:
    print(err)                      # this prints: division by zero

然后第二次尝试,将 1/0 替换为 raise ZeroDivisionError...

try:
    raise ZeroDivisionError
except ZeroDivisionError as err:
    print(err)                      # this prints: (nothing)

它什么都不打印。异常不是来自raise,和一般表达式一样吗?

另外,如何更清楚地理解这种差异?

所有异常都是 BaseException 的子class,因此所有 built-in 异常都应具有 args 属性。

args:

The tuple of arguments given to the exception constructor. Some built-in exceptions (like OSError) expect a certain number of arguments and assign a special meaning to the elements of this tuple, while others are usually called only with a single string giving an error message.

当您引发异常时,args 元组或字符串可以作为第一个参数提供。

try:
    raise ZeroDivisionError("error")
except ZeroDivisionError as err:
    print(err)  # prints "error"

except Exception as err:中的err是Exception实例,当你print(err)时,你实际上是在调用Exception的__str__方法。大多数 Exception class's __str__ return's args,因为它是 BaseException 的默认行为; __str__ 将 return 否则,如果异常 class 覆盖 BaseException 的 __str__

当你提出一个普通的 ZeroDivisionError 时,你没有提供 args,并且 ZeroDivisionError 没有自定义的 __str__ 方法,因此它打印了 args 默认情况下,a.k.a args = None.


关于你的问题:

Isn't an exception came from raise, same as the a general expression?

是的。他们是一样的。

try:
    raise ZeroDivisionError("division by zero")
except ZeroDivisionError as err:
    print(err)       

这将输出与 1/0 相同的结果。


我继续挖掘 source code//(整数除法)和 /(真除法)的错误信息略有不同。但基本上它们是这样定义的:

if (size_b == 0) {
        PyErr_SetString(PyExc_ZeroDivisionError,
                        "division by zero");
        return -1;
    }

size_b 是除数。如您所见,1/0 或任何除以零都会引发 ZeroDivsionError,其中 args 设置为 "division by zero""integer division or modulo by zero",具体取决于您的除法。