• 24.Python文件I/O(二)【异常处理&断言assert】


    每篇前言:


    在这里插入图片描述

    Python文件I/O(二)

    知识点补给站:

    • 注意:
      当代码出现了异常,后面的代码都不会执行;
      异常本身是类。

    • 在 Python 中所有的异常都是继承自 BaseException

    • 直接分为四大类:
      SystemExit:Python退出异常;
      KeyboardInterrupt: 键盘打断(Ctrl+C);
      GeneratorExit: 生成器退出(前面讲过了哦~);
      Exception: 普通异常(只会使用这部分的异常)。

    最基本的try…except…语句:

    try:
        print(11)       # 这是正确的,会打印出来
        print(a)        # a没定义,所以会出现异常
        print(22)       # 因为上面一句出现了异常,所以即使这句是正确的,也不会打印
    except:
        print('这里出现了异常')
        
    输出:
    11
    这里出现了异常
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.1 异常处理

    try:
        正常的操作
    except Exception1[, Exception2[,...ExceptionN]]][,Argument]as err:
    	发生异常,执行这块代码
    else:
    	如果没有异常执行这块代码
    finally:
    	退出try时总会执行执行这块代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 捕获具体的异常:
      except 后面可以写上捕获具体的异常类型 ,
      还可以通过as 把捕获的异常信息 储存到后面的变量里面。
    • 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。但是需要注意的是try 后面必须跟上 except子句!
    try:
    	pass
    except TabError:
    	pass
    except NameError:
    	pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
    except (RuntimeError, TypeError, NameError):
        pass
    
    • 1
    • 2
    • 最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。
      比如,我们并没有tmp.txt这个文件,下述代码会输出什么呢?
    # -*- coding: utf-8 -*-
    """
    __author__ = 小小明-代码实体
    """
    import sys
    
    try:
        f = open('tmp.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
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    • 再比如我们还是没有testfile这个文件,下述代码会输出什么呢?如果有又会输出什么呢?大家自行尝试哦~
    # -*- coding: utf-8 -*-
    """
    __author__ = 小小明-代码实体
    """
    try:
        fh = open("testfile", "r")
        try:
            fh.write("这是一个测试文件,用于测试异常!!")
        finally:
            print("关闭文件")
            fh.close()
    except IOError as value:
        print("Error: 没有找到文件或读取文件失败:", value)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    • 关于 Exception 及其 子类 的解释:
      代码中会出现的异常都是 Exception 的子类, 因此在 except 中只需要在最后加上 Exception 即可;
      在捕获异常的过程中,会从上倒下依次对比异常,找到之后就不会再往后查找。

    1.1.1 抛出异常

    Python 使用 raise 语句抛出一个指定的异常(注意:raise是主动抛出后面写的异常类型)。例如:

    >>>raise NameError('HiThere')
     Traceback (most recent call last):
       File "<stdin>", line 1, in ?
     NameError: HiThere
    
    • 1
    • 2
    • 3
    • 4

    可以自己写自定义的异常:

    class WuMou(Exception):
    	pass
    raise WuMou('出现错误')
    
    • 1
    • 2
    • 3

    输出为:

    Traceback (most recent call last):
      File "C:/my/pycharm_work/ceshi.py", line 3, in <module>
        raise WuMou('出现错误')
    __main__.WuMou: 出现错误
    
    • 1
    • 2
    • 3
    • 4

    可以捕获这个异常:

    class WuMou(Exception):
    	pass
    
    try:
    	raise WuMou('出现错误')
    except WuMou as h:
    	print(h)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出为:

    出现错误
    
    • 1
    • raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
    • 如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
    try:
        raise NameError('HiThere')
    except NameError:
        print('An exception flew by!')
        raise
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    结合捕获异常一起使用:
    例子:

    try:
        while True:                   #可以结束死循环
            if 1 == 1:
                raise NameError('出现错误啦')
    except Exception as e:
        print(e)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出:

    出现错误啦
    
    • 1

    小总结:

    • 将可能会发生异常的代码放在try中,就可以得到异常,并做相应处理
    • except用来接受异常,并且可以抛出或者返回异常
    • else在没有异常的时候会执行,finally不管是否有异常,都会执行

    1.1.2 自定义异常

    异常类继承自 Exception 类,可以直接继承,或者间接继承,例如:

    # -*- coding: utf-8 -*-
    """
    __author__ = 小小明-代码实体
    """
    class MyError(Exception):
        def __init__(self, value):
            self.value = value
    
        def __str__(self):
            return str(self.value)
    
    try:
        raise MyError(2 * 2)
    except MyError as e:
        print('My exception occurred, value:', e.value)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    raise MyError('oops!')
    
    • 1

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

    class Error(Exception):
        pass
    
    class InputError(Error):
        def __init__(self, expression, message):
            self.expression = expression
            self.message = message
    
    class TransitionError(Error):
        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
    • 大多数的异常的名字都以"Error"结尾,就跟标准的异常命名一样。

    1.1.3 python异常体系

    【官方文档~】

    BaseException
     +-- SystemExit
     +-- KeyboardInterrupt
     +-- GeneratorExit
     +-- Exception
          +-- StopIteration
          +-- StopAsyncIteration
          +-- ArithmeticError
          |    +-- FloatingPointError
          |    +-- OverflowError
          |    +-- ZeroDivisionError
          +-- AssertionError
          +-- AttributeError
          +-- BufferError
          +-- EOFError
          +-- ImportError
          |    +-- ModuleNotFoundError
          +-- LookupError
          |    +-- IndexError
          |    +-- KeyError
          +-- MemoryError
          +-- NameError
          |    +-- UnboundLocalError
          +-- OSError
          |    +-- BlockingIOError
          |    +-- ChildProcessError
          |    +-- ConnectionError
          |    |    +-- BrokenPipeError
          |    |    +-- ConnectionAbortedError
          |    |    +-- ConnectionRefusedError
          |    |    +-- ConnectionResetError
          |    +-- FileExistsError
          |    +-- FileNotFoundError
          |    +-- InterruptedError
          |    +-- IsADirectoryError
          |    +-- NotADirectoryError
          |    +-- PermissionError
          |    +-- ProcessLookupError
          |    +-- TimeoutError
          +-- ReferenceError
          +-- RuntimeError
          |    +-- NotImplementedError
          |    +-- RecursionError
          +-- SyntaxError
          |    +-- IndentationError
          |         +-- TabError
          +-- SystemError
          +-- TypeError
          +-- ValueError
          |    +-- UnicodeError
          |         +-- UnicodeDecodeError
          |         +-- UnicodeEncodeError
          |         +-- UnicodeTranslateError
          +-- Warning
               +-- DeprecationWarning
               +-- PendingDeprecationWarning
               +-- RuntimeWarning
               +-- SyntaxWarning
               +-- UserWarning
               +-- FutureWarning
               +-- ImportWarning
               +-- UnicodeWarning
               +-- BytesWarning
               +-- ResourceWarning
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    1.2 拓展——断言

    问题一: 如何能在代码中强制要求一个条件满足 ?
    问题二: 是否有专门的语法来完成 ?

    • 断言 assert
    • 断言语句是将调试断言插入程序的一种便捷方式

    assert 的语法规则是:

    • 表达式返回 True 不报错
    • 表达式返回 False 报错 报 AssertionError

    来个简单的例子:

    a = input('你是谁:')
    assert a == '吴某','你不是吴某'
    print('欢迎你 吴某')
    
    • 1
    • 2
    • 3

    第一种输出为:

    你是谁:吴某
    欢迎你 吴某
    
    • 1
    • 2

    第二种输出为:

    你是谁:中国
    Traceback (most recent call last):
      File "C:/my/pycharm_work/ceshi.py", line 2, in <module>
        assert a == '吴某','你不是吴某'
    AssertionError: 你不是吴某
    
    • 1
    • 2
    • 3
    • 4
    • 5

    升级一点的例子:

    a = input('你是谁:')
    try:
        assert a == '吴某','你不是吴某'
        print('欢迎你 吴某')
    except AssertionError as f:
        print(f)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    第一种输出:

    你是谁:吴某
    欢迎你 吴某
    
    • 1
    • 2

    第二种输出:

    你是谁:中国
    你不是吴某
    
    • 1
    • 2
  • 相关阅读:
    阿尔萨斯监控平台&普罗米修斯监控平台对服务器资源的监控
    Unity地面交互效果——1、局部UV采样和混合轨迹
    manim边学边做--MathTex
    使用非递归的方式实现归并排序
    Guava中的封装的Map操作
    测试/开发程序员难过的坎30岁,是一个程序员伤不起的年龄......
    数据结构:Map和Set(2):相关OJ题目
    数组的对象
    lottie 动画在 vue 中的使用
    Django在PyCharm中启动失败的解决办法
  • 原文地址:https://blog.csdn.net/qq_44907926/article/details/125509315