面向对象之异常处理

异常处理

1.什么是异常:

  • 代码发生错误之后,程序就中断了

2.什么是异常处理

  • 当代码出现异常时,通过某种方式不让程序中断,合理地跳过去

3.为什么要有异常处理

  • 增强用户体验感
  • 使代码更有健壮性,容错性

4.异常处理的两种方式

  • if else 只能处理简单的异常,如果需要考虑的方面比较多,不适合
  • 利用try的方式进行异常处理

5.什么时候用万能处理,什么时候用多分支

  • 如果对错误信息不关心,只是想要排除错误让程序继续运行,用万能
  • 如果对错误信息要进行明确的分流,让程序多元化开发,用分支

6.错误分类

  • 语法错误:这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正
  • 逻辑错误

7.具体举例分析

7.1语法错误

if 2 < 3            ---------不加冒号
	print("没加冒号")
dic = {"name";"alex"}    ----字典冒号换成分隔号

7.2逻辑错误

#用户输入不完整(空),或者输入不是数字,报错
num = input("请示入数字:")
print(int(num))
dic = {"name":"海狗","age":18}
print(dic["hobby"]) #字典的键不存在

7.3异常种类

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
class A:
    country = "中国"

    def func(self):
        pass

foo = A()
print(foo.x)
结果:AttributeError: 'A' object has no attribute 'x'
print(1/0)
结果:ZeroDivisionError: division by zero
num = input("请输入数字:")
if num.isdecimal():
    print(int(num))  #我们的正统程序放到了这里,其余的都属于异常处理范畴
elif num.isspace():
    print("输入的是空格,执行此处")
elif len(num) == 0:
    print("什么都没有,为空执行此处")
else:
    print("其他错误,执行这里")

7.4 if 判断处理异常

def foo():
    print("正常运行")
dic = {"1":foo}

while True:
    choose = input("请输入数字").strip()
    if not choose or choose not in dic:
        continue
    dic[choose]()
    break

7.5 异常处理的"私人订制" --try

7.5.1 基本结构

  • try:
    	被检测的正常代码
    except 异常类型:
    	try中一旦检测到异常,就执行这个位置逻辑
    
  • f = open("text")
    g = (line.strip() for line in f)
    
    for line in g:
        print(line)
    else:
        f.close()
    
try:
    f = open('a.txt')
    g = (line.strip() for line in f)
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
except StopIteration:
    f.close()
next(g)会触发迭代f,依次next(g)就可以读取文件的一行行内容,无论文件text有多大,同一时刻内存中只有一行内容。
提示:g是基于文件句柄f而存在的,因而只能在next(g)抛出异常StopIteration后才可以执行f.close()

7.5.2 异常类只能处理指定的异常情况

s = "hellokity"
try:
    int(s)  #ValueError
except IndexError as e: #错误类型不对,报错
    print(e)
try:
    num = int(input("请输入数字:"))#输入不是数字,执行except
    dic = {"name":"alex"} #只有num输入数字才执行此处
    print(dic["age"]) #执行到就报错
except ValueError: #只捕捉num的错误
    print(666)

7.5.3 多分支

try:
    num = int(input("请输入数字:")) #输入数字才正确
    dic = {"name":"加薪"}
    print(dic["age"])  #只能捕捉,查无此键
    lst = [1,2,3]
    print(lst[11])    #索引超标
    print("只要运行到错的就执行except")
except ValueError:
    print('输入的有非数字元素')
except KeyError:
    print('没有此键')
except IndexError:
    print('没有此下标')
print(666)

7.5.4 万能异常捕捉

try:
    num = int(input("请输入数字:")) #输入数字才正确
    dic = {"name":"加薪"}
    print(dic["age"])  #只能捕捉,查无此键
    lst = [1,2,3]
    print(lst[11])    #索引超标
    print("只要运行到错的就执行except")
except Exception as e:
    print(e)
print(666)

7.5.5 多分支 加 万能处理

7.5.6 主动抛出异常

try:
    raise TypeError('类型错误')
except Exception as e:
    print(e)

7.5.7 try except else finally

try:
    dic = {"name: "加薪"}
    # print(dic['age'])
    l1 = [1, 2]
    # print(l1[100])
    print(111)
except KeyError:
    print('没有此键')
except IndexError:
    print('没有此下标')
else: #有异常,不执行
    print('如果没有出现异常则执行这里')
finally: #一定会执行
    print('finally 666')

except 必须依赖于try, else必须依赖于except和try finally只是依赖于try

try:
    dic = {"name":"加薪"}
    print(dic['age'])
    l1 = [1, 2]
    print(l1[10])
    print(111)
finally: #执行完此句才报错
    print('finally 666')
    结果:先执行finally语句,后报错
def foo():
    try:
        print(111)
        return 666
    finally:
        print(888)
print(foo())
#结果:111  888  666

一定注意执行顺序 在return结束函数之前,执行finally代码.

7.5.8 断言:展现一种强硬的态度

# assert 条件
name = "alex"
n1 = input("请输入用户名:")
assert name == n1  #正确执行,错误报错
print(111)
print(222)
assert 1 == 1
# print("断言为真")
assert 1 != 2   #为假报错
print("为真运行")

7.5.9 自定义异常 python中给你提供的错误类型很多,但是不是全部的错误

class AlexError(BaseException):
    def __init__(self,msg):
        self.msg = msg

    def __srt__(self):
        return self.msg

try:
    raise AlexError("自定义错误类型") #调用__init__
except AlexError as e:
    print(e)  #调用__str__
原文地址:https://www.cnblogs.com/lvweihe/p/11342351.html