Skip to main content
 首页 » 编程设计

python之为什么 "raise Exception"没有结果

2025年05月04日14mq0036

如果我有一个 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 设置为 “被零除” 或 “整数除法或以零取模” 取决于您的除法。