一、raise函数的作用
抛出自定义的异常,stackoverflow社区里面常说的“Manually raising (throwing) an exception in Python”,这个manually解释的就很到位,是人工的,自己定义的异常。
有的人可能就感觉很奇怪了,我想让程序好好运行还来不及,怎么还想着运行错误呢?事实上,异常的种类有很多,对于python这个语言来说不是异常,但对于使用者或者programmer来说就是异常。举个简单例子,比如需要做个年龄输入,对于python来说,输入整数,小数都没有限制(只要programmer不限制)。但是从实际出发,不可能有小数的年纪。
二、raise函数使用举例
(1)raise函数常规使用方法举例
try:
raise Exception
except Exception:
#在这个输入遇到异常时的代码
**注意:**1)如果不使用try…except这种形式,那么直接抛出异常,不会执行后续代码。笔者认为这可能受制于python是解释性语言的原因。2)其中的Exception可以替换为各种系统内建错误。那么有哪些内建错误呢?在python中可以查看python官方文档,这个网站上详细给出了各种类型错误;或者在Google里面搜索“python built in exception”,都可以看到详细的系统内建的错误。
(2)运用raise函数抛出自定义异常
created by xiaolong date:2021年05月07日
class ValueError(Exception):
def __init__(self, age):
self.age = age
def __str__(self):
return str(self.age)
age = input('请输入年龄:')
try:
if int(age) < 0:
*raise ValueError*
except ValueError as VE:
print("输入的年龄小于零啦,age =", VE)
用法小结:1)raise后面可以直接跟一个class名,但是这个class必须是Exception的子类。2)__str__函数可以返回想要显示给用户的值。
(3)raise函数的一些其他用法
上面两种用法是常用的一些用法,下面介绍一些其他不同的raise抛出异常的语法。在stackoverflow问答这个网站里面介绍会比较详细。
1)只有一个raise
def somefunction():
print("some cleaning")
a=10
b=0
result=None
try:
result=a/b
print(result)
except Exception: #Output ->
somefunction() #some cleaning
raise #Traceback (most recent call last):
#File "python", line 8, in <module>
#ZeroDivisionError: division by zero
这里面就用到了一个单raise,他会自动re-raise,再次抛出上一个exception(异常)。如果先前没有异常,那么他就会抛出typeerror exception。
2)raise exception (args) from original_exception
class MyCustomException(Exception):
pass
a=10
b=0
reuslt=None
try:
try:
result=a/b
except ZeroDivisionError as exp:
print("ZeroDivisionError -- ",exp)
raise MyCustomException("Zero Division ") from exp
except MyCustomException as exp:
print("MyException",exp)
print(exp.__cause__)
输出结果:
ZeroDivisionError -- division by zero
MyException Zero Division
division by zero
这个raise exception (arg) from original_exception,作用是:exception能够从original_exception获取更多的信息。
三、需要注意的要点以及推荐用法
(1)需要注意的要点
1)可能会隐藏bug
def demo_bad_catch():
try:
raise ValueError('Represents a hidden bug, do not catch this')
raise Exception('This is the exception you expect to handle')
except Exception as error:
print('Caught this error: ' + repr(error))
>>> demo_bad_catch()
Caught this error: ValueError('Represents a hidden bug, do not catch this',)
要点:避免使用非常概括的exception(比如上面例子中的ValueError),而使用比较具体的exception。
2)精确的except子句不会抓住非常概括的exception。
def demo_no_catch():
try:
raise Exception('general exceptions not caught by specific handling')
except ValueError as e:
print('we will not catch exception: Exception')
>>> demo_no_catch()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in demo_no_catch
Exception: general exceptions not caught by specific handling
(2)推荐用法
1)raise句子可以给随性所欲的arg,可以用好这些arg
raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz')
try:
some_code_that_may_raise_our_value_error()
except ValueError as err:
print(err.args)
output:
('message', 'foo', 'bar', 'baz')
2)最好不要修改error。
你可以使用sys.exc_info()记录错误发生的type,, value,traceback,但是需要引用sys库。(语句为import sys)。最好不要修改sys.exc_info()中的内容,如果确实要修改可以把修改前的值赋给arg,保留在exception中。
import sys
def error():
raise ValueError('oops!')
def catch_error_modify_message():
try:
error()
except ValueError:
error_type, error_value, traceback = sys.exc_info()
print(error_type, error_value, traceback)
catch_error_modify_message()