2023年11月29日发(作者:)

Pythonraise⽤法

能否⼿动抛出⼀个异常吗?

答案是肯定的,Python允许程序⾃⾏引发异常,使⽤ raise 语句即可。

异常是⼀种很“主观”的说法,以下⾬为例,假设⼤家约好明天去爬⼭郊游,如果第⼆天下⾬了,这种情况会打破既定计划,就属于⼀种异常;但对于正在期盼天降⽢霖的农民⽽⾔,

如果第⼆天下⾬了,他们正好随⾬追肥,这就完全正常。

很多时候,系统是否要引发异常,可能需要根据应⽤的业务需求来决定,如果程序中的数据、执⾏与既定的业务需求不符,这就是⼀种异常。由于与业务需求不符⽽产⽣的异常,必须

由程序员来决定引发,系统⽆法引发这种异常。

如果需要在程序中⾃⾏引发异常,则应使⽤ raise 语句,该语句的基本语法格式为:

raise [exceptionName [(reason)]]

其中,⽤ [] 括起来的为可选参数,其作⽤是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在

抛出异常时,将不附带任何的异常描述信息。

也就是说,raise 语句有如下三种常⽤的⽤法:

raise:单独⼀个 raise。该语句引发当前上下⽂中捕获的异常(⽐如在 except 块中),或默认引发 RuntimeError 异常。

raise 异常类名称:raise 后带⼀个异常类名称。该语句引发指定异常类的默认实例。

raise 异常类名称(描述信息):在引发指定异常的同时,附带异常的描述信息。

上⾯三种⽤法最终都是要引发⼀个异常实例(即使指定的是异常类,实际上也是引发该类的默认实例),raise 语句每次只能引发⼀个异常实例。

例如:

>>> raise

Traceback (most recent call last):

File "", line 1, in

raise

RuntimeError: No active exception to reraise

>>> raise ZeroDivisionError

Traceback (most recent call last):

File "", line 1, in

raise ZeroDivisionError

ZeroDivisionError

>>> raise ZeroDivisionError("除数不能为零")

Traceback (most recent call last):

程序执⾏结果为:

输⼊⼀个数:a

引发异常: ValueError('a 必须是数字',)

Traceback (most recent call last):

File "D:", line 4, in

raise ValueError("a 必须是数字")

ValueError: a 必须是数字

这⾥重点关注位于 except 块中的 raise,由于在其之前我们已经⼿动引发了 ValueError 异常,因此这⾥当再使⽤ raise 语句时,它会再次引发⼀次。

当在没有引发过异常的程序使⽤⽆参的 raise 语句时,它默认引发的是 RuntimeError 异常。例如:

try:

a = input("输⼊⼀个数:")

if(not t()):

raise

except RuntimeError as e:

print("引发异常:",repr(e))

程序执⾏结果为:

输⼊⼀个数:a

引发异常: RuntimeError('No active exception to reraise',)

except raise 同时使⽤

在实际应⽤中对异常可能需要更复杂的处理⽅式。当⼀个异常出现时,单靠某个⽅法⽆法完全处理该异常,必须由⼏个⽅法协作才可完全处理该异常。也就是说,在异常出现的当前⽅

法中,程序只对异常进⾏部分处理,还有些处理需要在该⽅法的调⽤者中才能完成,所以应该再次引发异常,让该⽅法的调⽤者也能捕获到异常。

为了实现这种通过多个⽅法协作处理同⼀个异常的情形,可以在 except 块中结合 raise 语句来完成。如下程序⽰范了except 和 raise 同时使⽤的⽅法:

class AuctionException(Exception):

很多时候,程序可选择引发⾃定义异常,因为异常的类名通常也包含了该异常的有⽤信息。所以在引发异常时,应该选择合适的异常类,从⽽可以明确地描述该异常情况。在这种情形