24.Python文件I/O异常处理&断言assert

Posted 孤寒者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.1 异常处理

try:
    正常的操作
except Exception1[, Exception2[,...ExceptionN]]][,Argument]as err:
	发生异常,执行这块代码
else:
	如果没有异常执行这块代码
finally:
	退出try时总会执行执行这块代码
  • 捕获具体的异常:
    except 后面可以写上捕获具体的异常类型 ,
    还可以通过as 把捕获的异常信息 储存到后面的变量里面。
  • 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。但是需要注意的是try 后面必须跟上 except子句!
try:
	pass
except TabError:
	pass
except NameError:
	pass
  • 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
except (RuntimeError, TypeError, NameError):
    pass
  • 最后一个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

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

  • 关于 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

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

class WuMou(Exception):
	pass
raise WuMou('出现错误')

输出为:

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

可以捕获这个异常:

class WuMou(Exception):
	pass

try:
	raise WuMou('出现错误')
except WuMou as h:
	print(h)

输出为:

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


结合捕获异常一起使用:
例子:

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

输出:

出现错误啦

小总结:

  • 将可能会发生异常的代码放在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)

raise MyError('oops!')


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

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
  • 大多数的异常的名字都以"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 拓展——断言

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

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

assert 的语法规则是:

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

来个简单的例子:

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

第一种输出为:

你是谁:吴某
欢迎你 吴某

第二种输出为:

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

升级一点的例子:

a = input('你是谁:')
try:
    assert a == '吴某','你不是吴某'
    print('欢迎你 吴某')
except AssertionError as f:
    print(f)

第一种输出:

你是谁:吴某
欢迎你 吴某

第二种输出:

你是谁:中国
你不是吴某

以上是关于24.Python文件I/O异常处理&断言assert的主要内容,如果未能解决你的问题,请参考以下文章

python-异常&断言

JUnit4 & JUnit5 异常断言

Spark记录-Scala异常处理与文件I/O

Swift开发之异常处理及断言

学习笔记 5月31日(周一):内容3 - 4 申明和访问控制 && 流程控制异常处理和断言

学习笔记 5月31日(周一):内容3 - 4 申明和访问控制 && 流程控制异常处理和断言