美文网首页
python错误与异常处理

python错误与异常处理

作者: 北游_ | 来源:发表于2018-05-13 13:47 被阅读10次

    该笔记是根据慕课网中相关视频学习记录。
    视频地址:https://www.imooc.com/learn/457

    错误和异常的概念

    概念

    错误的概念

    1. 语法错误:代码不符合解释器或者编译器语法
    2. 逻辑错误:不完整或者不合法输入或者计算出先问题

    异常的概念

    1. 程序遇到逻辑或者算法问题
    2. 运行过程中计算机错误(内存不够或者IO错误)

    区别

    错误

    • 代码运行前的语法或者逻辑错误
    • 语法错误在执行前修改
    • 逻辑错误无法修改

    异常

    1. 异常产生, 解释器检查到错误且认为是异常,抛出异常
    2. 异常处理, 截获异常,忽略或者种植程序处理异常

    常见的错误

    • 变量未赋值直接引用 错误信息为: NameError
    • 语法错误: SyntaxError
    • 打开不存在文件时 错误信息为:IOError
    • 算术运算除数为0时 错误信息为:ZeroDivision
    • 强制类型转换时元数据不符合转换规则 错误信息为:ValueError
    • 在IDE中使用 Ctrl+C 中断程序执行时 错误信息为:KeyboardInterupt

    try-except 异常处理

    代码示例:

        try:
            print("测试代码")
        except Exception e:
            print("异常处理代码")
    
    1. try 用来捕获 print("测试代码") 中的异常,并且将异常就给except来处理
    2. except 用力啊处理异常,如果处理异常和设置捕获异常 Exception 指向的一致,使用 print ("异常处理代码") 来处理异常

    try-except-else :处理多个异常

    代码示例

        try:
            f = open('1.txt', 'r')
            # 读取两个字节的内容
            line = f.read(2)
            num = int(line)
            print("read the value is {}".format(num))
        except IOError e:
            print("catch IOError ", e)
    
        except ValueError e:
            print("catch ValueError ", e)
    
        else:
            print("it's fine, No Error")
    
    • 上述例子中会有两个 bug 一个是文件不存在,另一个是读取的数据值(有字母)无法做 int() 强制转换。
      所以通过两个except捕获异常
    • else 的作用是对无异常时的操作,看情况添加

    try-finally语句

    代码示例:

        try:
            f = open('1.txt', 'r')
            res = int(f.read())
            print(res)
        finally:
            print("file close")
            f.close()
    

    上述代码执行逻辑:

    • 当 try 中的代码块执行无异常时,正常执行结束后,执行 finally 中的代码块,打印信息和关闭文件。
    • 当 try 中的代码块执行有异常时,会先执行finally中的内容,打印信息和关闭文件,同时返回异常信息给python解释器。

    try-finally 执行规则:

    try-finally 无论是否会检测到异常,都会执行finally代码。

    try-finally 语句作用:

    为异常处理事件提供 清理机制,用来关闭文件或者释放系统资源。


    try-except-finally

    代码示例:

        try: 
            f = open('1.txt', 'r')
            line = f.read(2)
            num = int(line)
            print("read num={}".format(num))
        except IOError e:
            print("catch IOError", e)
        except ValueError e:
            print("catch ValueError", e)
        finally:
            try:
                print("close file")
                f.close()
            except NameError e:
                print("catch NameError",e)
    

    上述代码执行逻辑

    try 中的代码块执行打开文件,读取文件中的2个字节信息,转换为整型并打印出结果。

    • 若没有出现异常,执行玩try代码块之后,执行 finally 中的 try 代码块
    • 当出现异常时,先执行异常的处理函数,再执行 finally 中的代码块,再 finally 中也有对异常的处理,主要是在,文件为被正常打开的情况下,关闭会出现异常,故会执行 finally-except 中的内容

    try-except-finally 执行规则

    • 若 try 语句没有捕获异常,执行完 try 代码块后,执行 finally 。
    • 若 try 语句捕获到异常,首先执行except处理错误,然后执行 finally 。

    try-except-else-finally语句

    语法格式

        try:
            try_suite
        except:
            do_except
        else:
            do_else
        finally:
            do_finally
    

    try-except-else-finally执行规则

    1. 若 try 语句没有捕获异常,执行完 try 代码块后,执行 else 代码段,最后执行 finally
    2. 若 try 语句捕获异常,首先执行 except 处理错误,然后执行 finally

    with……as语句

    语法格式

        with context [as var]:
            with_suite
    
    1. with 语句用来代替 try-except-finally语句,使代码更加简洁;
    2. context 表达式返回的是一个对象,该对象需要支持上下文协议
    3. var 用来保存 context 返回的对象,支持单个返回值为变量、多个返回值为元组类型
    4. with_suit 使用 var 变量来对 context 返回对象进行操作

    with 语句示例

    with open("1.txt","r") as f:
        for line in f.readlines():
            print(line)
    

    示例解释

    1. open("1.txt","r") 打开文件的操作会生成一个临时的对象
    2. with open("1.txt","r") as f 表示将刚刚生成的临时对象赋值给变量 f
    3. with 中的代码执行(无异常)完成时,会 自动关闭文件,若 with 代码块有错误异常,则不关闭文件,被报错中断,故需要使用 try-except 捕捉异常。
    4. 对于上述的自动关闭功能可以使用 print(f.closed) 来验证,结果为 True 表示已关闭,False 表示未关闭

    with 语句实质是上下文管理

    1. 上下文管理协议: 包含方法 enter() 和 exit() , 支持该协议的对象要实现这两个方法
    2. 上下文管理器: 定义执行 with 语句时要在建立 运行时上下文 ,负责执行 with 语句块上下文中的进入退出操作
    3. 进入上下文管理器: 调用管理器 enter()方法,如果设置 as var 语句,var 变量接受 enter() 方法 返回值
    4. 退出上下文管理器: 调用管理器 exit 方法,对资源进行清理,对文件进行关闭。

    定义一个类学习上下文管理机制:

        class Mycontext(object):
            def __init__(self, name):
                self.name = name
    
            def __enter__(self):
                print("__enter__")
                return self
            
            def do_self(self):
                print("do_self")
    
            def __exit__(self, exc_type, exc_value, traceback):
                # exc_type 参数表示 错误类型
                # exc_value 参数表示 错误类型描述信息
                # traceback 参数表示 出错的堆栈信息,根据堆栈信息可以知道代码是在哪一行出了错误
                print("__exit__")
                print("Error:", exc_type, "info:", exc_value)
    
        if __name__ == '__main__':
            with Mycontext("test_context") as f:
                print(f.name)
                f.do_self()
    

    返回结果:

    _enter_
    test_context
    do_self
    _exit_
    Error: None info: None

    该执行结果表明 with 语句会先执行 _enter() 方法实例化一个对象,再 _init() 初始化对象, 再执行相关操作,最后会执行 _exit_() 操作,这是with语句规定的。

    针对上述例子的异常捕获

        class Mycontext(object):
            def __init__(self, name):
                self.name = name
    
            def __enter__(self):
                print("__enter__")
                return self
            
            def do_self(self):
                print("do_self")
                a
    
            def __exit__(self, exc_type, exc_value, traceback):
                # exc_type 参数表示 错误类型
                # exc_value 参数表示 错误类型描述信息
                # traceback 参数表示 出错的堆栈信息,根据堆栈信息可以知道代码是在哪一行出了错误
                print("__exit__")
                print("Error:", exc_type, "info:", exc_value)
    
        if __name__ == '__main__':
            with Mycontext("test_context") as f:
                print(f.name)
                f.do_self()
    

    执行结果

    _enter_
    test_context
    do_self
    _exit_
    Error: <class 'NameError'> info: name 'a' is not defined
    Traceback (most recent call last):
    File "F:/脱产学习2017.10.27/兄弟连python/haolong/alice_code/demo/day7/test.py", line 27, in <module>
    f.do_self()
    File "F:/脱产学习2017.10.27/兄弟连python/haolong/alice_code/demo/day7/test.py", line 13, in do_self
    a
    NameError: name 'a' is not defined

    该执行结果表示代码再执行过程中出现在异常,会先执行 _exit_()方法,再将异常抛出给python解释器。

    应用场景

    1. 文件操作;
    2. 进程线程之间互斥对象,例如互斥锁;
    3. 支持上下文的其他对象

    raise 语句和 assert 语句

    raise 语句
    raise 语句用于主动抛出异常
    语法格式: raise [exception[,args]]

    • exception: 异常类
    • args: 描述异常信息的字符串

    assert 语句
    断言语句:assert语句用于检测表达式是否为真,如果为假,引发 AssertionError 错误;

    语法格式:assert expression[,args]

    • expression: 表达式
    • args:判断条件的描述信息,字符串

    应用场景

    定义函数或类中的方法,可以使用assert对传入的参数进行格式判断。在通过 try-except 对异常进行捕获和处理


    标准异常和自定义异常

    标准异常:
    标准异常:python 内建异常,程序执行前就已经存在。

    说明

    1. BaseException 类,所有异常都是继承该类,若except中没有指明异常的类型,则使用 BaseException 捕获所有的异常
    2. KeyboardInterrupt 类是捕获用户使用 Ctrl + C 中断程序导致的异常,直接继承 BaseException 类
    3. Exception 类是系统、python解释器异常的基类:
    • 该类继承于 BaseException 类
    • 该类下还有 SyntaxError 类、NameError 类、IOError 类、 ImportError 类等多个子类
    1. SystemExit 类是当 python 解释器退出时触发这个类,出现异常
      对于不明白的类,建议访问 python 官网,查看详细信息

    自定义异常:

    1. python 允许自定义异常,用于描述 python 中没有涉及的异常情况。
    2. 自定义异常必须继承 Exception 类或者Exception 类下的子类
    3. 自定义异常只能主动触发 raise方法触发

    自定义异常示例:

    • 自定义异常:
      class FileError(IOError):
          pass
    
    • 产生自定义异常
      raise FileError, "file Error"
    
    • try-except 捕获主动触发的异常
      try:
          raise FileError, "file Error"  
      except FileError as e:
          print(e)
    

    相关文章

      网友评论

          本文标题:python错误与异常处理

          本文链接:https://www.haomeiwen.com/subject/rakldftx.html