python之异常、异常的捕获、else、finally、主动抛出异常raise

注意:       

         当一个函数的返回值是一个布尔值的时候,如果把这个函数做为条件放到 if 或者while后面的时候,后面不用再写==True,也就是说:此时的   if 函数名   等价于 if 函数名 ==True ,如果函数返回True,则原式就等于if True代表条件成立,就会执行if条件下面的代码。反之,如果函数返回的是False,就代表条件不成立,就不会执行if下面的代码。但是,如果一个函数返回False,才执行if语句的话,可以写成:if not 函数名

一、异常

程序错误分两种情况:

(1)语法错误。写出来的代码不符合python的语法规则。

(2)异常。代码本身没有错误,但是在运行的时候却报错了,这就叫异常。

例如:语法错误举例。

num = aasint(input("请输入一个整数:"))  # aasint 不是python里面的函数                  

print(   # 后面少了半个括号

例如:异常的举例。

num = int(input("请输入一个整数:")) # 这就叫代码本身没有错误
print("hello word")

# 执行,输入abc结果报错,这就是异常
请输入一个整数:abc
Traceback (most recent call last):
  File "D:/study_python/yy_daima/yichang/buhuoyichang.py", line 1, in <module>
    num = int(input("请输入一个整数:"))
ValueError: invalid literal for int() with base 10: 'abc'

进程已结束,退出代码 1

从上面代码中可以看到,当代码一旦遇到错误,程序就会停止运行,剩下的代码也就不会再执行了,就比如print("hello word")这行就没执行。

程序停止运行,并且抛出错误信息的这个动作,叫做抛出异常。

为了更好的保证程序的健壮性和稳定性,通常都会在代码中加入捕获异常的机制。

二、捕获异常

在程序开发过程中,如果有些代码的执行不确定是否正确,可以给它加个try....except来捕获异常。

语法格式:

try:
    可能出现异常的代码
except:
    出现异常后要执行的代码

一旦try里面的代码发生异常,程序就会自动执行except里面的代码,此时,程序就不会再因为报错而终止了;如果没有发生异常,那么except里面的代码也就不会被执行。

例如:

try:
    num = int(input("请输入一个整数:"))
except:
    print("输入的不对!")

结果:
请输入一个整数:2         # 没有发生异常,不会执行except

进程已结束,退出代码 0


请输入一个整数:a      # 错误输入,出现异常,执行except
输入的不对!

进程已结束,退出代码 0

三、捕获不同类型的异常

在程序执行的过程中,可能会遇到各种各样的报错信息,为了提高代码的友好度,可以根据不同的报错信息,做出不同的响应。就好比,我错了,那我具体哪错了。

语法格式:

try:
    可能出现异常的代码
except 异常类型1:
    出现异常后要执行的代码
except 异常类型2:
    出现异常后要执行的代码
......

例如:由用户输入两个整数,然后输出这两个数相除后的结果。

try:
    num1 = int(input("请输入num1:"))
    num2 = int(input("请输入num2:"))
    print(num1 / num2)
except ValueError:
    print("请输入纯数字!")
except ZeroDivisionError:
    print("除数不能为0!")

结果:
请输入num1:1
请输入num2:2
0.5

进程已结束,退出代码 0


请输入num1:f
请输入纯数字!

进程已结束,退出代码 0


请输入num1:1
请输入num2:d
请输入纯数字!

进程已结束,退出代码 0


请输入num1:5
请输入num2:0
除数不能为0!

进程已结束,退出代码 0


例如:对一个能够进行加减乘除运算的计算器,进行异常捕获。

try:
    num1 = int(input("请输入第一个数"))
    num2 = int(input("请输入第二个数"))
    opt = input("请输入+、-、*、/中的任意一个字符:")
    if opt == "+":
        print(num1 + num2)
    elif opt == "-":
        print(num1 - num2)
    elif opt == "*":
        print(num1 * num2)
    elif opt == "/":
        print(num1 / num2)
    else:
        print("输入的运算符不正确")
except ValueError:
    print("请输入纯数字")
except ZeroDivisionError:
    print("除数不能为0!")
结果:
请输入第一个数1
请输入第二个数2
请输入+、-、*、/中的任意一个字符:/
0.5


请输入第一个数a
请输入纯数字


请输入第一个数2
请输入第二个数0
请输入+、-、*、/中的任意一个字符:/
除数不能为0!

四、捕获未知错误——except Exception as result

通过故意输入错误的数据,可以看到程序的报错类型,但有些错误不一定能很快就试验出来,所以,对于这些未知的错误,可以用except Exception as result进行捕获。

语法格式:

try:
  可能出现异常的代码
except Exception as result:   #result是个变量名,可以随便起,一般习惯写result
    print(result)    # 出现未知异常时执行的代码
                                
               # print(result)就是把捕获的这个异常提示信息给打印出来。
           # 也就是说,让我能看到这里为啥报错了。

但是一般用的不多,因为,在编写代码时候基本就会把可能报错的类型都考虑进入了,如果没考虑进去,用这种方式得到的错误信息也不一定能看的懂。

例如:让一个字符串和一个整数用加号进行拼接,使用except Exception as result来捕获异常。

try:
    a = "23"   # 字符串
    b = 1        # 整型
    print(a + b)     # 这俩不能进行拼接
except Exception as result:
    print(result)

结果:
can only concatenate str (not "int") to str

进程已结束,退出代码 0

五、没有发生异常时才执行的代码——else

如果程序在运行过程中,没有发生异常,还需要额外再执行一些代码,就可以用else。也就是说,只有try里面的代码不发生异常,才会执行else里面的代码

格式:

try:
  可能出现异常的代码
except Exception as result:    # 或者这里按异常类型来写
    发生异常时要执行的代码    
else:
    没有发生异常时要执行的代码

例如:由用户输入两个整数,然后输出这两个数相除后的结果。

try:
    num1 = int(input("请输入num1:"))
    num2 = int(input("请输入num2:"))
    print(num1 / num2)
except ValueError:
    print("请输入纯数字的字符串")
except ZeroDivisionError:
    print("除数不能为0!")
else:
    print("代码没有发生异常")

结果:
请输入num1:1
请输入num2:2
0.5
代码没有发生异常      # 也就是说,只有try里面的代码不发生异常,才会执行else里面的代码


请输入num1:1
请输入num2:0
除数不能为0!

六、不管有没有发生异常,都要执行的代码——finally

语法:

try:
  可能出现异常的代码
except Exception as result:   # 或者这里按异常类型来写
    发生异常时要执行的代码
finally:
    不管有没有发生异常,都要执行的代码

例如:把上面的else改成finally.

try:
    num1 = int(input("请输入num1:"))
    num2 = int(input("请输入num2:"))
    print(num1 / num2)
except ValueError:
    print("请输入纯数字的字符串")
except ZeroDivisionError:
    print("除数不能为0!")
finally:
    print("不管有没有发生异常,我都要执行")
结果:
请输入num1:1
请输入num2:2
0.5
不管有没有发生异常,我都要执行


请输入num1:a
请输入纯数字的字符串
不管有没有发生异常,我都要执行

七、综合

把上面的所有语法写在一起。

try:
    可能出现异常的代码
except 异常类型1:
    出现异常后要执行的代码
except 异常类型2:
    出现异常后要执行的代码
except Exception as result:
    出现未知异常时要执行的代码
else:
    没有发生异常时才执行的代码
finally:
    不管有没有发生异常, 都要执行的代码

例如:

try:
    num1 = int(input("请输入num1:"))
    num2 = int(input("请输入num2:"))
    print(num1 / num2)
except ValueError:
    print("请输入纯数字的字符串")
except ZeroDivisionError:
    print("除数不能为0!")
except Exception as result:  # 捕获未知错误
    print("未知错误:", result)
else:
    print("代码没有发生异常")  # else发生异常就不执行
finally:
    print("代码执行完毕")     # 不管有没有发生异常,都会执行

结果:
请输入num1:1
请输入num2:2
0.5
代码没有发生异常
代码执行完毕

请输入num1:a
请输入纯数字的字符串
代码执行完毕

八、人为的主动抛出异常

抛出异常使用关键字raise,python中还提供了一个Exception异常类。

格式:

raise Exception("对异常的描述")

例如:用户设置密码,如果密码长度小于6,则抛出异常。

str1 = input("请输入密码:")
if len(str1) < 6:
    raise Exception("密码至少要设置为6位数!")
else:
    print("密码设置成功!")
print("代码执行结束")

结果:
请输入密码:123ab
Traceback (most recent call last):
  File "D:/study_python/yy_daima/yichang/buhuoyichang.py", line 121, in <module>
    raise Exception("密码至少要设置为6位数!")
Exception: 密码至少要设置为6位数!


请输入密码:aabbcc
密码设置成功!
代码执行结束

解析:第一次输入时,输入的是5个字符,所以if条件成立,就会抛出异常,而后面的print("代码执行结束")这行代码也不执行了。说明,主动抛出的异常同样也会导致程序的终止。所以,无论是系统自动抛出的异常还是人为主动抛出的异常,都需要进行捕获,才能让程序继续往下运行。

即:只要是异常,都要进行捕捉,否则代码报错程序执行中断。

优化上面的代码:加入捕获异常的机制。

try:
    str1 = input("请输入密码:")
    if len(str1) < 6:
        raise Exception("密码至少要设置为6位数!")

    else:
        print("密码设置成功!")
except Exception as result:  # 加入这两行代码
    print(result)

print("代码执行结束")

结果:
请输入密码:abc
密码至少要设置为6位数!
代码执行结束

请输入密码:123456
密码设置成功!
代码执行结束

这样代码就会更加友好,无论有没有发生异常,最后一行代码print("代码执行结束")都能执行了。

例如:主动抛出异常举例。

定义两个变量:name、age,分别通过input函数进行输入。

要求:当name中有数字字符时,或者,age小于等于0时,都抛出异常,并进行捕捉。

法1:

try:
    name = input("请输入姓名:")
    for i in name:
        if i >= "0" and i <= "9":
            raise Exception("名字输的不对,名字中不能有数字!")
    age = int(input("请输入年龄:"))
    if age <= 0:
        raise Exception("年龄输的不对,年龄必须大于0!")
except Exception as result:
    print(result)

结果:
请输入姓名:123
名字输的不对,名字中不能有数字!

请输入姓名:a
请输入年龄:-10
年龄输的不对,年龄必须大于0!

# 正确的输入
请输入姓名:a    
请输入年龄:8

进程已结束,退出代码 0

法2:可以把判断名字有没有数字,这个拿出来写到外面,封装成一个函数。

def digital(str1):  # 定义一个函数,专门用来判断名字里有没有数字
    for i in str1:
        if i >= "0" and i <= "9":
            return True  # 如果有数字,返回True
    return False  # 如果没有数字,返回False


try:
    name = input("请输入姓名:")
    if digital(name):  # 调用函数,把name作为实参传进去
        raise Exception("名字输的不对,名字中不能有数字!")
    age = int(input("请输入年龄:"))
    if age <= 0:
        raise Exception("年龄输的不对,年龄必须大于0!")
except Exception as a:
    print(a)

结果:
请输入姓名:123         # 当输入第一个的时候出现错误,立马捕获
名字输的不对,名字中不能有数字!

请输入姓名:abc
请输入年龄:-10
年龄输的不对,年龄必须大于0!

注意踩坑!!!

上面的代码中,都是把name和age的输入函数分开来写的,所以,只要把哪个写错了就会立马报错,这样代码比较智能。然而下面的代码就不那么智能了,存在一个问题,如果把姓名跟年龄的输入都一起写到最上面,那么当俩都出现错误时,只会捕捉到第一个异常。例如下面的第一个输入中,名字跟年龄都输错了,但最终却只捕获到了一个,显然这种是不友好的。

try:
    name = input("请输入姓名:")
    age = int(input("请输入年龄:"))
    for i in name:
        if i >= "0" and i <= "9":
            raise Exception("名字输的不对,名字中不能有数字!")
    if age <= 0:
        raise Exception("年龄输的不对,年龄必须大于0!")
except Exception as result:
    print(result)

结果:
请输入姓名:123
请输入年龄:-10
名字输的不对,名字中不能有数字!   # 名字、年龄都错了,但只捕获到了一个异常


请输入姓名:1
请输入年龄:8
名字输的不对,名字中不能有数字!   # 名字错,年龄对

注意:

        当一个函数的返回值是一个布尔值的时候,如果把这个函数做为条件放到 if 或者while后面的时候,后面不用再写==True,也就是说:此时的   if 函数名   等价于 if 函数名 ==True ,如果函数返回True,则原式就等于if True代表条件成立,就会执行if条件下面的代码。反之,如果函数返回的是False,就代表条件不成立,就不会执行if下面的代码。但是,如果一个函数返回False,才执行if语句的话,可以写成:if not 函数名

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值