python错误与异常处理

该笔记是根据慕课网中相关视频学习记录。
视频地址: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: 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
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 内建异常,程序执行前就已经存在。

python错误与异常处理_第1张图片

说明

  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错误与异常处理)