如果我有一个 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 的子类,因此所有内置异常都应该有一个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) 时,您实际上是在调用__str__ 异常的方法。大多数Exception class's __str__ return's args ,因为这是 BaseException 的默认行为;如果异常类覆盖 BaseException 的 __str__,则 __str__ 将以其他方式返回。
当你引发一个普通的 ZeroDivisionError 时,你没有提供 args,并且 ZeroDivisionError 没有自定义的 __str__ 方法,因此它默认打印 args,也就是 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 设置为 “被零除” 或 “整数除法或以零取模” 取决于您的除法。
