异常

目录:

    概要

    异常

    常见异常

    异常处理

    不常见语法

    主动抛异常

    自定义异常

概要:

1.什么是异常
    是错误发生前的一种信号,如果没有正确处理这个异常信息,将终止程序执行,并抛出异常信息

2.为什么要处理异常 
    为了程序能够正常运行,提高健壮性

3.异常处理的语法:
    1.try:
        可能出错的代码
      except 异常的类型:
        错误发生后执行的代码

    2.except 异常的类型| (各种类型,,) | (万能异常BaseException) as 获取异常的对象:
        错误发生后执行的代码
        
    3.else:
        必须在except下面finally上面
        没有异常时执行
        
    4. finally:
            无论异常是否发生,都会执行,用于回收资源
4.上面时候使用异常
    不能确定异常发生的原因时,或者知道原因但是无法解决时

5.raise有什么用
    什么时候需要主动抛出异常?当用户使用时没有按照规范使用
    语法: raise 类型(详细信息)

6.自定义异常类
    什么需要自定义:系统提供的异常类和我们想要描述的错误不匹配时
    语法:用一个class,继承BaseException

7.assert 断言
    assert 跟一个bool类型的表达式
    后续的功能需要前面的某个条件成立,才能执行
    反过来说,只有某个条件成立才能执行后续代码

异常:


不应该滥用try except
什么时候用? 如果你知道为什么出错,应该把代码修改正确,而不是加上try except
你不清楚为什么会发生异常! 这时候用try
什么是异常?
    异常是错误发生前的一种信号
    如果没有人来处理这个信号,程序就会中断执行并抛出错误信息
异常的分类:
    1.语法检查异常,这种异常是最低级异常,绝对不应该,也非常好避免
        如果是编译器,会自动提示
        如果是文本编辑器,在你运行代码前,解释器会检查语法
    2.运行时异常(逻辑异常)
        这种异常只有在代码被执行时才能发现
        我们要处理的重点就是运行时异常
        特点:在没有运行代码前,是无法发现的
            如果运行时异常已经发生并且没有正确处理他,就抛出错误信息
            并且中断程序的执行,这是要我们学习异常解决的问题
异常的组成
    1.追踪信息(具体发生异常的位置,以及函数的调用顺序)--Traceback
    2.异常的类型(错误的类型)--IndexError
    3.异常的消息(详细的错误信息)--list index out of range

我们之所以学习异常处理
    为的是让我们的程序更加稳定(健壮性)不容易崩溃

 常见异常:

常见的发生原因:
NameError 找不到这个名字 要么变量 要么函数
ValueError 在调用一个函数时给的的值不正确
TypeError 类型错误 例如字符串与数字加减乘除 调用一个不能被调用的类型
ZeroDivisionError 除数不能为0
KeyError 没有这个key
IndexError 索引不存在
StopIteration 没有更多的值可以迭代
FileNotFoundError 文件不存在
io.UnsupportedOperation 文件的操作不支持
AttributeError 没有这个属性
KeyboardInterrupt 程序被强行终止 ctrl+c

异常处理:

要处理异常
    要学的就是一个新的语法

今后使用最多的写法:
try:
    这里放可能出现异常的代码
except 异常的类型:
    打印信息

    当异常发生并且异常类型匹配时,执行except中的代码
注意:一旦try中有代码抛出了异常,后面的代码全都不执行

基本语法:

print("staring.....")
try:
    name
except NameError:
    print("名字找不到!")
print("end.......")

# 多种异常类型处理 print("staring.....") try: name [][-1] pass except NameError: print("名字找不到!") except IndexError: print("索引超出范围") print("end.......") # 当代码可能出现多种异常时的写法 print("staring.....") try: # name # [][-1] 1/0 pass except NameError: print("名字找不到!") except IndexError: print("索引超出范围") except ZeroDivisionError: print("除数不能为0") print("end.......")
# 当代码可能出现多种异常时的写法2 print("staring.....") try: {}["aaa"] # name # [][-1] 1/0 except (NameError,IndexError,ZeroDivisionError): print("可能名字找不到! 可能所以超出范围 可能除数为0") print("end.......")
# 上面两种写法,都可以处理多种异常,但是异常类型太多了,不可能全写完 # 万能异常类型Exception或BaseException基于OOP的继承和多态 print("staring.....") try: # {}["aaa"] # name # [][-1] 1/0 except Exception: print("可能名字找不到! 可能所以超出范围 可能除数为0") print("end.......")

不常用语法:

语法1
try:
except:
else: #try中没有发生异常时执行

语法2
try :
except :
finally : #无论是否发生异常,都会执行finally,可以用来回收系统资源!

用途:

# 使用finally来回收资源
try:
    f = open(r"G:\PythonHomework\31\笔记\1今日内容","rt",encoding="utf-8")
    f.read()
    # f.write("123")
except Exception:
    print("发生异常了")
finally:
    print("关闭文件!")
    f.close()#文件关闭后,程序不结束,内存中f依然存在

主动抛异常:

当程序中有一些限制 然而用户没有遵守 我们可以主动抛出异常
语法:
    raise 异常类型(异常的详细信息)
    类型必须是BaseException的子类


代码:
age = input("请输入整型的年龄:")
if not age.isdigit():
    raise TypeError("你输入的不是整型!")
age = int(age)
print("十年后你%s岁" % (age + 10) 

断言:

断言:可以理解断定,就是很清楚,很明确.分为两部分代码
什么时候需要断定?
    下面的代码必须依赖上面代码的正确数据
语法:assert,结果为Bool的表达式
    如果值为True,则继续往下执行;为False,抛出一个AssertionError表示断言失败
没有assert也可以使用if来玩,assert仅仅是简化了代码

示例代码:

# 第一部分代码,负责产生一个列表
li = []
li.append(1)
# li.append(2)
# 这里一定要确保数据是有效的
# if len(li) < 1:
#     raise ValueError("列表中没有数据!")
assert len(li) > 0
# 需要使用列表中的数据来完成任务 如果没有数据无法完成
print(li[0])

自定义异常:

当系统提供的这些异常类型和你要描述的错误不匹配时,就需要自定义异常类型

写法:class 自定义异常类型名称(BaseException):
总结一下:之所以自定义异常类型,是为了更具体描述你的错误,让使用者一眼就看出了
关键点:1.如何自定义异常类型
      2.在except中,使用as来获取异常对象

自定义异常代码:

# 你随便输入一句话 看我喜不喜欢  不喜欢我就抛出异常
# 自定义异常类
class UnlikeError(BaseException):#继承基类
    def __init__(self,msg,text):
        self.msg = msg
        self.text = text
# 函数中可能抛出异常
def hello():
    text = input("输入一段话:")#你真丑
    if text == "你真帅":
        print("你说得对!")
    else:
        raise UnlikeError("你再考虑一下...","另一个参数")#主动抛出异常
# 捕获异常
try:
    hello()
# 获取异常对象
except UnlikeError as e:#as 对象 , 通过对象调用属性
    print(e)#('你再考虑一下...', '另一个参数')
    print(e.msg)#你再考虑一下...
    print(e.text)#另一个参数

 

posted @ 2018-11-01 16:54  ChuckXue  阅读(188)  评论(0编辑  收藏  举报