异常处理

# 单分支   最简单的异常处理
l = ['login','register']
for num,i in enumerate(l,1):
    print(num,i)

try:      # ****** 在会出问题的这一行 写一个try,一旦try里面的代码出了问题,程序会继续往下走,找到except
    num = int(input('num >>>')) #被异常处理机制包围的代码
    print(l[num - 1])
except ValueError :
    # except处理的异常必须和实际报错的异常是相同的才能处理
    # except 后面跟的异常名称和实际报错的一样时,就会继续往下执行print
    # 如果except后面写的异常名字和实际的不一样的时候, 仍然会报错
    print('请输入一个数字')
print(l[num - 1])


l = ['login','register']
for num,i in enumerate(l,1):
    print(num,i)
try:      # ****** 在会出问题的这一行 写一个try,一旦try里面的代码出了问题,程序会继续往下走,找到except
    num = int(input('num >>>')) #被异常处理机制包围的代码
    print(l[num - 1])
except ValueError :
    print('请输入一个数字')
try:
    print(l[num - 1])
except IndexError :
    print("只能输入1或2")
# 但是这么写有点麻烦, 这就需要用多分支来处理异常



# 多分支
l = ['login','register']
for num,i in enumerate(l,1):
    print(num,i)
try:
    num = int(input('num >>>'))
    print(l[num - 1])
except ValueError :
    # 多分支的特点就是,从try往下走,一旦找到了符合的except(比如说是第一个ValueError),就不再往下走了
    # 从上向下报错的代码只要找到一个和报错类型相符的分支就执行这个分支中的代码,然后直接退出分支
    print('请输入一个数字')
except IndexError :
    # 如果找不到能处理和报错类型相同的分支,会一直往下走,最后还是没有找到就会报错
    print('只能输入1或2')



# 多分支合并
l = ['login','register']
for num,i in enumerate(l,1):
    print(num,i)
try:
    num = int(input('num >>>'))
    print(l[num - 1])
except (ValueError,IndexError) : #把两个except合并到一起, 写成一个元组的形式
    print('您输入的内容不合法')



# 万能异常
# 等所有的程序都开发完了,测试也完了,才用万能异常
def buy():
    print('buy')
    name #NameError 例如 程序内部的错误

def back():
    print('back')
    [][1] #IndexError  例如 这个程序内部的错误

def show():
    print('show')
    1/0  #ZeroDivisionError

#  *** 下面这个结构会在以后的项目里经常用到 ***
def main():
    l = [('购物',buy),('退货',back),('查看订单',show)]#列表里套元组
    while True:
        for num,i in enumerate(l,1):
            print(num,i[0])
        num = int(input('num >>>'))
        print(l[num - 1])
        try:
            func = l[num - 1][1] # *** num = 1  buy ***
            func()   #调用 buy 函数 在执行func的时候可能会出现错误,比如 NameError,所以在上面加一个异常处理  try
        except Exception: #万能处理
            #这样可以保证程序不闪退
            print('用户在选择了%s操作之后发生了不可知的异常' % l[num - 1][0])
main()


# 万能异常 as语法  能够将具体错误信息打印出来
def buy():
    print('buy')
    name

def back():
    print('back')
    [][1]

def show():
    print('show')
    1/0

def main():
    l = [('购物',buy),('退货',back),('查看订单',show)]
    while True:
        for num,i in enumerate(l,1):
            print(num,i[0])
        num = int(input('num >>>'))
        print(l[num - 1])
        try:
            func = l[num - 1][1]
            func()
        except Exception as e:
            print(e)   # 一般情况下只打印 e
            #print(e.args, e.__traceback__.tb_lineno, e.__traceback__.tb_frame)
            print('用户在选择了%s操作之后发生了不可知的异常' % l[num - 1][0])
main()



# 万能异常,相当于except Exception
try:
    name       #NameError
    [][1]      #IndexError
    int('aaa') #ValueError
except:
    print(123)



# 多分支 + 万能异常 : 万能异常应该永远放在异常处理的最下面
def buy():
    print('buy')
    name

def back():
    print('back')
    [][1]

def show():
    print('show')
    1/0

def main():
    l = [('购物',buy),('退货',back),('查看订单',show)]
    while True:
        for num,i in enumerate(l,1):
            print(num,i[0])
        try:
            num = int(input('num >>>')) #这里遇到问题 执行多分支异常
            print(l[num - 1])
            func = l[num - 1][1]    #这里遇到问题 就执行万能异常
            func()
        except (ValueError,IndexError) :
            print('您输入的内容不合法')
        except Exception as e:
            print(e)
            #print(e.args, e.__traceback__.tb_lineno, e.__traceback__.tb_frame)
            print('用户在选择了%s操作之后发生了不可知的异常' % l[num - 1][0])
main()



# 最常见的处理异常的组合
try:
    pass
except (ValueError,IndexError):
    print('针对性的处理')
except Exception as e: #为了打印出具体的错误信息
    print(e)
    print('通用性的处理')
# else分支
try:
    print('aaa')  # 给某某某发邮件
    # name
    # [][1]
    # 1/0
except NameError:   # 网络不稳定,邮箱地址错误
    print('name error')
except IndexError:
    print('index error')
except Exception as e:
    print('Exception')
else:  # 当try中的代码不发生异常的时候 走else分支  如果例子中的邮件发送成功了 else进行一些处理
    print('else')
#else 是一个万能分支
#应用场景: 给某人发邮件,


# finally分支
try:
    print('aaa')  # 给某某某发邮件
    name
    # [][1]
    # 1/0
except NameError:   # 网络不稳定,邮箱地址错误
    print('name error')
except IndexError:
    print('index error')
except Exception as e:
    print('Exception')
else:  # 当try中的代码不发生异常的时候 走else分支  如果发送成功了 进行一些处理
    print('else')
finally: # 无论有没有报错  都会被执行
    print('finally')


#无论如何都会被执行的 应用场景
def func():
    f = open('file')
    try:
        while True:
            for line in f:
                if line.startswith('a'):
                    return line #line已经在内存, 即使先关闭了文件也可以拿到
    except:
        print('异常处理') # 即使有异常也会关闭 文件资源
    finally:   # 即使return  也会先执行fianlly中的代码  finally的用法一
        f.close()


# 第二种语法:
try:
    f = open('www','w')
    f.read() #以写的形式打开, 这一行去读,肯定会报错,即使报错也会先关闭文件,再抛出错误. 
finally:   # 即使遇到报错,程序结束,也会先执行finally中的代码,然后再结束程序 finally的用法二
    f.close()
    print('文件已经关闭了')
# finally用来回收一些操作系统的资源 : 数据库连接 打开的文件句柄 网络连接


# 异常处理的几种情况(重点) ******
try ... except  (常用的组合)
try ... except ... else (else作用是报try 成功)
try ... finally
try ... except ... finally
try ... except ... else ... finally (finally的作用是资源回收)



# 主动抛出异常 : 是给其他开发者用的
raise ValueError
raise ValueError('你写的不对')
django是别人写的程序 框架 --> 程序员用



# 断言 - 语法 (条件判断, 主要用来看源码用的, 一般在程序中不会用的)
assert 1==2  # assert 后面只能接受一个布尔值  False 会抛异常

assert 1==1  # True 满足条件就往下走 打印 123456 相当于if
print(123456)

#跟上面的效果一样
if 1 == int(input()):
    pass
else:
    raise AssertionError


# 自定义异常 :面向对象之后

# 异常处理的忠告,在最外层的异常处理应该在所有的开发结束之后才放
main()
    # sdhjlkghl
try:
    main()
except Exception as e:
    # 把e报错写到文件里
例如 程序内部的错误
原文地址:https://www.cnblogs.com/kenD/p/9520251.html