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: <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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容

  • 一、简介 Python最强大的结构之一就是它的异常处理能力,所有的标准异常都使用类来实现,都是基类Exceptio...
    随风化作雨阅读 3,073评论 0 1
  • 本文讲解了python标准异常、什么是异常、异常处理的多种方法和实例等内容,需要的朋友可以参考下 python提供...
    小白python教程阅读 1,254评论 0 2
  •   选择排序(Selection Sort)也是比较简单的排序算法,思路也比较直观。选择排序算法在每一步中选取最小...
    一笑小先生阅读 1,355评论 0 1
  • 关于应该过新历生日还是农历生日,我的观点是应该过新历生日,毕竟没有闰月这一说,自然是准确些。但是家里人的传统...
    freecati阅读 237评论 0 0
  • 好想回到那些年的春天 空气中弥漫着春天的气息 漫山遍野的红花白花粉花 各种大自然的香味扑鼻而来 还有鸟儿叽叽喳喳的...
    为梦想而努力的蜗牛阅读 129评论 0 0