Python raise用法
在前面章节的学习中,遗留过一个问题,即是否可以在程序的指定位置手动抛出一个异常?答案是肯定的,Python 允许我们在程序中手动设置异常,使用 raise 语句即可。
读者可能会感到疑惑,即我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢?首先要分清楚程序发生异常和程序执行错误,它们完全是两码事,程序由于错误导致的运行异常,是需要程序员想办法解决的;但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常。
其中,用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息。
也就是说,raise 语句有如下三种常用的用法:
1、raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。
2、raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。
3、raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。
可以看到,当用户输入的不是数字时,程序会进入 if 判断语句,并执行 raise 引发 ValueError 异常。但由于其位于 try 块中,因为 raise 抛出的异常会被 try 捕获,并由 except 块进行处理。
因此,虽然程序中使用了 raise 语句引发异常,但程序的执行是正常的,手动抛出的异常并不会导致程序崩溃。
这里重点关注位于 except 块中的 raise,由于在其之前我们已经手动引发了 ValueError 异常,因此这里当再使用 raise 语句时,它会再次引发一次。
当在没有引发过异常的程序使用无参的 raise 语句时,它默认引发的是 RuntimeError 异常。例如:
读者可能会感到疑惑,即我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢?首先要分清楚程序发生异常和程序执行错误,它们完全是两码事,程序由于错误导致的运行异常,是需要程序员想办法解决的;但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常。
raise 语句的基本语法格式为:
raise [exceptionName [(reason)]]
也就是说,raise 语句有如下三种常用的用法:
1、raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。
2、raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。
3、raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。
显然,每次执行 raise 语句,都只能引发一次执行的异常。首先,我们来测试一下以上 3 种 raise 的用法:
>>> raise Traceback (most recent call last): File "<pyshell#1>", line 1, in <module> raise RuntimeError: No active exception to reraise >>> raise ZeroDivisionError Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> raise ZeroDivisionError ZeroDivisionError >>> raise ZeroDivisionError("除数不能为零") Traceback (most recent call last): File "<pyshell#2>", line 1, in <module> raise ZeroDivisionError("除数不能为零") ZeroDivisionError: 除数不能为零
当然,我们手动让程序引发异常,很多时候并不是为了让其崩溃。事实上,raise 语句引发的异常通常用 try except(else finally)异常处理结构来捕获并进行处理。例如:
try: a = input("输入一个数:") #判断用户输入的是否为数字 if(not a.isdigit()): raise ValueError("a 必须是数字") except ValueError as e: print("引发异常:",repr(e))
程序运行结果为:
输入一个数:a 引发异常: ValueError('a 必须是数字',)
因此,虽然程序中使用了 raise 语句引发异常,但程序的执行是正常的,手动抛出的异常并不会导致程序崩溃。
raise不需要参数
正如前面所看到的,在使用 raise 语句时可以不带参数,例如:
try: a = input("输入一个数:") if(not a.isdigit()): raise ValueError("a 必须是数字") except ValueError as e: print("引发异常:",repr(e)) raise
程序执行结果为:
输入一个数:a 引发异常: ValueError('a 必须是数字',) Traceback (most recent call last): File "D:\python3.6\1.py", line 4, in <module> raise ValueError("a 必须是数字") ValueError: a 必须是数字
当在没有引发过异常的程序使用无参的 raise 语句时,它默认引发的是 RuntimeError 异常。例如:
try: a = input("输入一个数:") if(not a.isdigit()): raise except RuntimeError as e: print("引发异常:",repr(e))
程序执行结果为:
输入一个数:a 引发异常: RuntimeError('No active exception to reraise',)
浙公网安备 33010602011771号