一、异常处理
python解释器检测到错误,触发异常(也允许程序员自己触发异常)。程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关)。如果捕捉成功则进入另外一个处理分支,执行你为其定制的逻辑,使程序不会崩溃,这就是异常处理。
python解释器去执行程序,检测到了一个错误时,触发异常,异常触发后且没被处理的情况下,程序就在当前异常处终止,后面的代码不会运行,谁会去用一个运行着突然就崩溃的软件。所以你必须提供一种异常处理机制来增强你程序的健壮性与容错性。良好的容错能力,能够有效的提高用户体验,维持业务的稳定性。
程序运行中的异常可以分为两类:语法错误和逻辑错误。首先,我们必须知道,语法错误跟异常处理无关,所以我们在处理异常之前,必须避免语法上的错误。
异常就是程序运行时发生错误的信号,在python中,错误触发的异常如下
1.1 异常处理方式
1.1.1 使用if判断式
# 我们平时用if做的一些简单的异常处理 num1 = input('>>: ') # 输入一个字符串试试 if num1.isdigit(): int(num1) # 我们的正统程序放到了这里,其余的都属于异常处理范畴 elif num1.isspace(): print('输入的是空格,就执行我这里的逻辑') elif len(num1) == 0: print('输入的是空,就执行我这里的逻辑') else: print('其他情情况,执行我这里的逻辑') # 这些if,跟代码逻辑并无关系,显得可读性极差,如果类似的逻辑多,那么每一次都需要判断这些内容,就会倒置我们的代码特别冗长。
使用if判断式可以异常处理,但是if判断式的异常处理只能针对某一段代码,对于不同的代码段的相同类型的错误你需要写重复的if来进行处理。而且在你的程序中频繁的写与程序本身无关,与异常处理有关的if,会使得你的代码可读性极其的差。
1.1.2 python提供的特定的语法结构
part1:基本语法
1 try: 2 被检测的代码块 3 except 异常类型: 4 try中一旦检测到异常,就执行这个位置的逻辑
part2:单分支
1 a = [1,2,3] 2 d = {} 3 try: 4 a[3] 5 print(d['name']) 6 except IndexError as e: 7 print('下标越界',e) 8 except KeyError as e: 9 print('字典key不存在') 10 else: 11 print('正常运行')
下标越界 list index out of range
finally: 有没有出现异常都走这
1 a = [1,2,3] 2 d = {} 3 try: 4 a[3] 5 print(d['name']) 6 except Exception as e: # 所有异常都能捕捉到 7 print('出异常了',e) 8 else: 9 print('正常运行') 10 finally: 11 print('有没有出现异常都走这')
出异常了 list index out of range
有没有出现异常都走这
异常处理try except用法中,如果使用了return就不需要使用else
1 try: 2 cur.execute(sql) 3 except Exception as e: 4 print('mysql连接失败,%s' %sql) 5 # result = False # 如果使用了return 就不需要使用else 6 else: 7 ...
part3:多分支
1 l1 = [('电脑',16998),('鼠标',59),('手机',8998)] 2 while 1: 3 for key,value in enumerate(l1,1): 4 print(key,value[0]) 5 try: 6 num = input('>>>') 7 price = l1[int(num)-1][1] 8 except ValueError: 9 print('请输入一个数字') 10 except IndexError: 11 print('请输入一个有效数字') 12 #这样通过异常处理可以使得代码更人性化,用户体验感更好。
part4:万能异常
在python的异常中,有一个万能异常:Exception,他可以捕获任意异常。它是一把双刃剑,有利有弊,我们要视情况使用
如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么只有一个Exception就足够了。
如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了。我们可以使用多分支+万能异常来处理异常。使用多分支优先处理一些能预料到的错误类型,一些预料不到的错误类型应该被最终的万能异常捕获。需要注意的是,万能异常一定要放在最后,否则就没有意义了。
except Exception as e: 所有异常都能捕捉到
1 a = [1,2,3]
2 d = {}
3 try:
4 a[3]
5 print(d['name'])
6 except Exception as e: # 所有异常都能捕捉到
7 print('出异常了',e) 8 else: 9 print('正常运行')
出异常了 list index out of range
part5:try...else语句
1 try: 2 for i in range(10): 3 int(i) 4 except IndexError as e: 5 print(e) 6 else: 7 print('***********') #*********** 执行了此处 8 #当try语句中的代码没有异常,被完整地执行完,就执行else中的代码
小结
1 try: 2 # 可能发生异常的代码 3 except 异常类型1 as 变量名: 4 print(变量名) # 变量名存储的是具体的错误信息 5 except 异常类型2 as 变量名: 6 print(变量名) # 变量名存储的是具体的错误信息 7 except Exception as 变量名: 8 print(变量名) # 变量名存储的是具体的错误信息 9 else: 10 print('如果以上代码没有发生异常以及异常处理工作就执行这里的代码') 11 print('一般情况下else中的代码用来下结论') 12 # logging模块 13 finally: 14 print('不管代码是否有异常都会执行,且在函数中遇到return仍然会执行') 15 print('一般情况下用于这个函数中资源的回收')
1.2 断言
assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假。可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触发异常。
assert的异常参数,其实就是在断言表达式后添加字符串信息,用来解释断言并更好的知道是哪里出了问题。格式如下:
assert expression [, arguments]
assert 表达式 [, 参数]
assert len(lists) >=5,'列表元素个数小于5'
assert 2==1,'2不等于1'
备注:格式:assert 条件 , 条件为false时的错误信息 结果为raise一个AssertionError出来
1 # assert 条件 2 3 assert 1 == 1 4 5 assert 1 == 2
二、面向对象
概述
- 面向过程:根据业务逻辑从上到下写垒代码
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
- 面向对象:对函数进行分类和封装,让开发“更快更好更强…”
面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
while True:
if cpu利用率 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
if 硬盘使用空间 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
if 内存占用 > 80%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
|
随着时间的推移,开始使用了函数式编程,增强代码的重用性和可读性,就变成了这样
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def 发送邮件(内容)
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
while True:
if cpu利用率 > 90%:
发送邮件('CPU报警')
if 硬盘使用空间 > 90%:
发送邮件('硬盘报警')
if 内存占用 > 80%:
发送邮件('内存报警')
|