• 菜鸟教程《Python 3 教程》笔记(19):错误与异常


    笔记带有个人侧重点,不追求面面俱到。

    19 错误和异常

    出处: 菜鸟教程 - Python3 错误和异常

    Python 有两种错误很容易辨认:语法错误异常

    19.1 assert(断言)

    assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,

    语法格式:

    assert expression [, arguments]
    
    • 1

    等效于:

    if not expression:
        raise AssertionError(arguments)
    
    • 1
    • 2

    实例:

    >>> assert 1==2    # 条件为 false 触发异常
    Traceback (most recent call last):
      File "", line 1, in <module>
    AssertionError
    
    >>> assert 1==2, '1 不等于 2'
    Traceback (most recent call last):
      File "", line 1, in <module>
    AssertionError: 1 不等于 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    19.2 异常处理

    个人理解: 进行异常处理是为了避免直接抛出异常而导致暴露,通过接收不同的异常可以进行针对性地处理(或者做出提示)。

    异常处理
    图片出处:菜鸟教程 - Python3 错误和异常

    19.2.1 try/except

    可以使用 try/except 语句异常捕捉。

    try 语句执行逻辑:

    1. 执行 try 子句;
    2. 如果没有异常发生,忽略 except 子句,try 子句执行后结束,如果在执行 try 子句的过程中发生了异常,那么 try 子句余下的部分将被忽略;
    3. 如果异常的类型和 except 之后的名称相符,那么对应的 except 子句将被执行,如果一个异常没有与任何的 except 匹配,那么这个异常将会传递给上层的 try 中

    一个 try 语句可能包含多个 except 子句,分别来处理不同的特定的异常,最多只有一个分支会被执行

    处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

    一个 except 子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:

    except (RuntimeError, TypeError, NameError):
        pass
    
    • 1
    • 2

    可以使用 Exception 捕获除了 SystemExitKeyboardInterruptGeneratorExit 之外的所有异常。 如果还想捕获这三个异常,可以将 Exception 改成 BaseException 即可。

    except Exception as err:
        print(err)
    
    • 1
    • 2

    最后一个 except 子句可以忽略异常的名称,它将被当作通配符使用。可以使用这种方法打印一个错误信息,然后再次把异常抛出:

    import sys
    
    try:
        f = open('myfile.txt')
        s = f.readline()
        i = int(s.strip())
    except OSError as err:
        print("OS error: {0}".format(err))
    except ValueError:
        print("Could not convert data to an integer.")
    except:
        print("Unexpected error:", sys.exc_info()[0])
        raise  # 抛出异常
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    19.2.2 try/except…else

    else 子句将在 try 子句没有发生任何异常的时候执行。使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到,而 except 又无法捕获的异常。

    for arg in sys.argv[1:]:
        try:
            f = open(arg, 'r')
        except IOError:
            print('cannot open', arg)
        else:
            print(arg, 'has', len(f.readlines()), 'lines')
            f.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    异常处理并不仅仅处理那些直接发生在 try 子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。

    19.2.3 try-finally 语句

    finally 语句无论异常是否发生都会执行。

    try:
        runoob()
    except AssertionError as error:
        print(error)
    else:
        try:
            with open('file.log') as file:
                read_data = file.read()
        except FileNotFoundError as fnf_error:
            print(fnf_error)
    finally:
        print('这句话,无论异常是否发生都会执行。')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    19.3 抛出异常

    Python 使用 raise 语句抛出一个指定的异常。raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。

    raise [Exception [, args [, traceback]]]
    
    • 1

    如果只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。

    >>> try:
            raise NameError('HiThere')  # 模拟一个异常。
        except NameError:
            print('An exception flew by!')
            raise
       
    An exception flew by!
    Traceback (most recent call last):
      File "", line 2, in ?
    NameError: HiThere
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    19.4 用户自定义异常

    可以通过继承 Exception 类来自定义异常类。大多数的异常的名字都以 “Error” 结尾,就跟标准的异常命名一样。

    当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类

    class Error(Exception):
        """Base class for exceptions in this module."""
        pass
    
    class InputError(Error):
        """Exception raised for errors in the input.
    
        Attributes:
            expression -- input expression in which the error occurred
            message -- explanation of the error
        """
    
        def __init__(self, expression, message):
            self.expression = expression
            self.message = message
    
    class TransitionError(Error):
        """Raised when an operation attempts a state transition that's not
        allowed.
    
        Attributes:
            previous -- state at beginning of transition
            next -- attempted new state
            message -- explanation of why the specific transition is not allowed
        """
    
        def __init__(self, previous, next, message):
            self.previous = previous
            self.next = next
            self.message = message
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    19.5 清理行为

    19.5.1 定义清理行为

    不管 try 子句里面有没有发生异常,finally 子句都会执行。如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后被抛出。

    19.5.2 预定义的清理行为

    关键词 with 语句可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法。就算在处理过程中出问题了,文件总是会关闭。

    19.5.3 with 关键字

    Python 中的 with 语句用于异常处理,封装了 try…except…finally 编码范式,提高了易用性。with 语句使代码更清晰、更具可读性, 它简化了文件流等公共资源的管理。在处理文件对象时使用 with 关键字是一种很好的做法。

    实例:

    with open('./test_runoob.txt', 'w') as file:
        file.write('hello world !')
    
    • 1
    • 2

    等效于:

    file = open('./test_runoob.txt', 'w')
    try:
        file.write('hello world')
    finally:
        file.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    with 语句实现原理建立在上下文管理器之上。

  • 相关阅读:
    Linux电话本的编写-shell脚本编写
    Rollup failed to resolve import
    SkyWalking快速上手(八)——sleuth+zipkin和SkyWalking的区别
    UE5自定义插件创建UserWidget蓝图
    机器学习:集成学习(Python)
    开放式运动耳机排行榜哪个好用,排行靠前的五款运动耳机分享
    Java 复习笔记 - Lambda 表达式 he 经典算法题
    0046【Edabit ★☆☆☆☆☆】【长方形面积】Area of a Rectangle
    java虚拟机类加载机制
    实时备案查询易语言代码
  • 原文地址:https://blog.csdn.net/weixin_44254041/article/details/132746002