0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Python错误及异常总结汇总

马哥Linux运维 来源:未知 作者:邓佳佳 2018-03-06 17:03 次阅读

前言

程序员的一生中,错误几乎每天都在发生。在过去的一个时期, 错误要么对程序(可能还有机器)是致命的,要么产生一大堆无意义的输出,无法被其他计算机或程序识别,连程序员自己也可能搞不懂它的意义。一旦出现错误,程序就会终止执行,直到错误被修正,程序重新执行。所以,人们需要一个”柔和”的处理错误的方法,而不是终止程序。同时,程序本身也在不断发展,并不是每个错误都是致命的,即使错误发生,编译器或是在执行中的程序也可以提供更多更有用的诊断信息,帮助程序员尽快解决问题。然而,错误毕竟是错误,一般都是停止编译或执行后才能去解决它。一小段代码只能让程序终止执行,也许还能打印出一些模糊的提示。当然,这一切都是在异常和异常处理出现之前的事了。

1. 错误

从软件方面来说,错误是语法或是逻辑上的。语法错误指示软件的结构上有错误,导致不能被解释器解释或编译器无法编译。这些错误必须在程序执行前纠正。当程序的语法正确后,剩下的就是逻辑错误了。逻辑错误可能是由于不完整或是不合法的输入所致;在其他情况下,还可能是逻辑无法生成,计算,或是输出结果需要的过程无法执行。这些错误通常分别被称为域错误和范围错误。

Python 检测到一个错误时,解释器就会指出当前流已经无法继续执行下去,这时候就出现了异常。

2. 异常

对异常的最好描述是: 它是因为程序出现了错误而在正常控制流以外采取的行为。这个行为又分为两个阶段: 首先是引起异常发生的错误,然后是检测(和采取可能的措施)阶段。

第一个阶段是在发生了一个异常条件(有时候也叫做例外的条件)后发生的。只要检测到错误并且意识到异常条件,解释器会引发一个异常。引发也可以叫做触发或者生成,解释器通过它通知当前控制流有错误发生。Python 也允许程序员自己引发异常,无论是 Python 解释器还是程序员引发的,异常就是错误发生的信号,当前流将被打断,用来处理这个错误并采取相应的操作,这就是第二阶段。

对异常的处理发生在第二阶段。异常引发后,可以调用很多不同的操作,可以是忽略错误(记录错误但不采取任何措施, 采取补救措施后终止程序),或是减轻问题的影响后设法继续执行程序。所有的这些操作都代表一种继续,或是控制的分支,关键是程序员在错误发生时可以指示程序如何执行。

类似 Python 这样支持引发和处理异常(这更重要)的语言,可以让开发人员可以在错误发生时更直接地控制它们。程序员不仅仅有了检测错误的能力,还可以在它们发生时采取更可靠的补救措施。由于有了运行时管理错误的能力,应用程序的健壮性有了很大的提高。

异常和异常处理并不是什么新概念。它们同样存在于 Ada,Modula-3,C++,Eiffel,以及 Java 中。异常的起源可以追溯到处理系统错误和硬件中断这类异常的操作系统代码。在 1965 年左右,PL/1 作为第一个支持异常的主要语言出现,而异常处理是作为一个它提供的软件工具。和其他支持异常处理的语言类似,Python 采用了 “try/尝试” 块和 “catching/捕获” 块的概念,而且它在异常处理方面更有”纪律性”。我们可以为不同的异常创建不同的处理器,而不是盲目地创建一个”catch-all/捕获所有”的代码。

3. python中常见异常

NameError:尝试访问一个未声明的变量

NameError表示我们访问了一个没有初始化的变量. 在 Python 解释器的符号表没有找到那个另人讨厌的变量. 我们将在后面的两章讨论名称空间, 现在大家可以认为它们是连接名字和对象的”地址簿”就可以了. 任何可访问的变量必须在名称空间里列出. 访问变量需要由解释器进行搜索, 如果请求的名字没有在任何名称空间里找到, 那么将会生成一个NameError异常.

ZeroDivisionError:除数为零

我们边的例子使用的是整数, 但事实上, 任何数值被零除都会导致一个ZeroDivisionError异常.

SyntaxError:Python 解释器语法错误

SyntaxError 异常是唯一不是在运行时发生的异常.它代表 Python 代码中有一个不正确的结构, 在它改正之前程序无法执行. 这些错误一般都是在编译时发生, Python 解释器无法把你的脚本转化为 Python 字节代码. 当然这也可能是你导入一个有缺陷的模块的时候.

IndexError:请求的索引超出序列范围

IndexError在你尝试使用一个超出范围的值索引序列时引发.

KeyError:请求一个不存在的字典关键字

映射对象, 例如字典, 是依靠关键字(keys)访问数据值的. 如果使用错误的或是不存在的键请求字典就会引发一个KeyError异常.

IOError:输入/输出错误

类似尝试打开一个不存在的磁盘文件一类的操作会引发一个操作系统输入/输出(I/O)错误. 任何类型的 I/O 错误都会引发IOError异常.

AttributeError:尝试访问未知的对象属性

我们在 myInst.hp 储存了一个值, 也就是实例 myInst 的 hp 属性. 属性被定义后, 我们可以使用熟悉的点/属性操作符访问它, 但如果是没有定义属性, 例如我们访问 hq 属性, 将导致一个AttributeError异常.

4. 检测和处理异常

异常可以通过try语句来检测。任何在try语句块里的代码都会被监测,检查有无异常发生。

try语句有两种主要形式:try-except和try-finally. 这两个语句是互斥的, 也就是说你只 能 使 用 其 中 的 一 种 . 一 个try语 句 可 以 对 应 一 个 或 多 个except子 句 , 但 只 能 对 应 一 个finally子句, 或是一个try-except-finally复合语句.

你可以使用try-except语句检测和处理异常. 你也可以添加一个可选的else子句处理没有探测到异常的时执行的代码. 而try-finally只允许检测异常并做一些必要的清除工作(无论发生错误与否), 没有任何异常处理设施. 正如你想像的, 复合语句两者都可以做到.

try-except 语句

最 常 见 的try-except语 句 语 法 如 下 所 示,它 由try块 和except块 (try_suite 和 except_suite )组成,也可以有一个可选的错误原因。

带有多个 except 的 try 语句

这种格式的 except 语句指定检测名为 Exception 的异常. 你可以把多个 except 语句连接在一起, 处理一个 try 块中可能发生的多种异常, 如下所示:

处理多个异常的 except 语句

我们还可以在一个 except 子句里处理多个异常,前提只是它们被放入一个元组里 , 如下:

Note:try语句块中异常发生点后的剩余语句永远不会到达(所以也永远不会执行)。一旦一个异常被引发,就必须决定控制流下一步到达的位置。剩余代码将被忽略,解释器将搜索处理器,一旦找到,就开始执行处理器中的代码。

如果没有找到合适的处理器,那么异常就向上移交给调用者去处理,这意味着堆栈框架立即回到之前的那个。如果在上层调用者也没找到对应处理器,该异常会继续被向上移交,直到找到合适处理器。如果到达最顶层仍然没有找到对应处理器,那么就认为这个异常是未处理的,Python 解释器会显示出跟踪返回消息,然后退出。

Python 提供给程序员的try-except语句是为了更好地跟踪潜在的错误并在代码里准备好处理异常的逻辑,这样的机制在其他语言(例如 C ) 是很难实现的,它的目的是减少程序出错的次数并在出错后仍能保证程序正常执行。作为一种工具而言,只有正确得当地使用它,才能使其发挥作用。

避免把大片的代码装入try-except中然后使用pass忽略掉错误,你可以捕获特定的异常并忽略它们,或是捕获所有异常并采取特定的动作。不要捕获所有异常,然后忽略掉它们。

异常参数

异常也可以有参数,异常引发后它会被传递给异常处理器。当异常被引发后参数是作为附加帮助信息传递给异常处理器的。虽然异常原因是可选的,但标准内建异常提供至少一个参数,指示异常原因的一个字符串。

异常的参数可以在处理器里忽略,但 Python 提供了保存这个值的语法,我们已经在上边接触到相关内容:要想访问提供的异常原因,你必须保留一个变量来保存这个参数。把这个参数放在except语句后,接在要处理的异常后面。

reason 将会是一个包含来自导致异常的代码的诊断信息的类实例。异常参数自身会组成一个元组,并存储为类实例 ( 异 常 类 的 实 例 ) 的 属 性 。上 边 的 第 一 种 用 法 中,reason 将 会 是 一 个Exception类的实例。

else 子句

我们已经看过else语句段配合其他的 Python 语句,比如条件和循环。至于try-except语句段,它的功能和你所见过的其他else没有太多的不同:在try范围中没有异常被检测到时,执行else子句。

在else范围中的任何代码运行前,try范围中的所有代码必须完全成功(也就是,结束前没有引发异常)。

finally 子句

finally子句是无论异常是否发生,是否捕捉都会执行的一段代码。你可以将finally仅仅配合try一起使用,也可以和try-except(else 也是可选的)一起使用,也可以使用独立的try-finally。

当然,无论如何,你都可以有不止一个的except子句,但最少有一个except语句,而else和finally都是可选的。A,B,C 和 D 是程序(代码块)。程序会按预期的顺序执行。(注意:可能的顺序是A-C-D[正常] 或 A-B-D[异常])。无论异常发生在 A,B,和/或 C 都将执行finally块。

另一种使用finally的方式是finally单独和try连用。这个try-finally语句和try-except区别在于它不是用来捕捉异常的。作为替代,它常常用来维持一致的行为而无论异常是否发生。我们得知无论try中是否有异常触发,finally代码段都会被执行。

try-except-else-finally语句

无论你选择什么语法,你至少要有一个except子句,而else和finally都是可选的。

with语句

with语句的目的在于从流程图中把try,except和finally关键字和资源分配释放相关代码统统去掉,而不是像try-except-finally那样仅仅简化代码使之易用。with语法的基本用法看上去如下:

这段代码试图打开一个文件,如果一切正常,把文件对象赋值给 f。然后,用迭代器遍历文件中的每一行,当完成时,关闭文件。无论在这一段代码的开始,中间,还是结束时发生异常,都会执行清理的代码,此外文件仍会被自动的关闭。

5. 触发异常

raise语句

raise语句对所支持是参数十分灵活,对应到语法上就是支持许多不同的格式.rasie 一般的用法是:

第一个参数,SomeExcpetion,是触发异常的名字.如果有,它必须是一个字符串,类或实例(详见下文).如果有其他参数(arg 或 traceback),就必须提供 SomeExcpetion.

第二个符号为可选的 args(比如参数,值),来传给异常.这可以是一个单独的对象也可以是一个对象的元组.当异常发生时,异常的参数总是作为一个元组传入.如果 args 原本就是元组,那么就将其传给异常去处理;如果 args 是一个单独的对象,就生成只有一个元素的元组(就是单元素元组).大多数情况下,单一的字符串用来指示错误的原因.如果传的是元组,通常的组成是一个错误字符串,一个错误编号,可能还有一个错误的地址,比如文件,等等.

最后一项参数,traceback,同样是可选的(实际上很少用它),如果有的话,则是当异常触发时新生成的一个用于异常-正常化(exception—normally)的追踪(traceback)对象.当你想重新引发异常时,第三个参数很有用(可以用来区分先前和当前的位置).如果没有这个参数,就填写 None.

6. 断言语句

断言语句等价于这样的 Python 表达式,如果断言成功不采取任何措施(类似语句),否则触发AssertionError(断言错误)的异常.assert 的语法如下:

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • python
    +关注

    关注

    55

    文章

    4777

    浏览量

    84397

原文标题:Python错误及异常总结汇总

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    对比Python与Java编程语言

    使得编写代码更加灵活,但也可能导致运行时错误。 Java 语法相对冗长,需要显式声明变量类型,增加了代码的可读性和安全性。 静态类型系统在编译时进行类型检查,减少了运行时错误。 二、性能 Python 解释型语言,运行速度通常比
    的头像 发表于 11-15 09:31 120次阅读

    嵌入式C编程常用的异常错误处理

    信息记录到非易失性存储器或通过串口输出。 总结 嵌入式C编程中的异常错误处理方法多种多样,选择合适的方法取决于具体的应用场景和系统要求。通过合理的错误处理机制,可以提高系统的
    发表于 08-06 14:32

    一站式统一返回值封装、异常处理、异常错误码解决方案—最强的Sping Boot接口优雅响应处理器

    1. 前言 统一返回值封装、统一异常处理和异常错误码体系的意义在于提高代码的可维护性和可读性,使得代码更加健壮和稳定。统一返回值封装可以避免每一个接口都需要手工拼装响应报文;统一异常
    的头像 发表于 06-20 15:42 446次阅读

    介绍一些常见的Modbus IO通信错误代码及其含义

    Modbus IO通信协议中的错误代码通常用于标识通信过程中出现的错误异常情况。
    的头像 发表于 03-06 09:03 2329次阅读

    如何使用linux下gdb来调试python程序

    如何使用linux下gdb来调试python程序  在Linux下,可以使用GDB(GNU调试器)来调试Python程序。GDB是一个强大的调试工具,可以帮助开发者诊断和修复程序中的错误。在本文
    的头像 发表于 01-31 10:41 2394次阅读

    如何解决C语言中的“访问权限冲突”异常?C语言引发异常原因分析

    如何解决C语言中的“访问权限冲突”异常?C语言引发异常原因分析  在C语言中,访问权限冲突异常通常是由于尝试访问未授权的变量、函数或其他数据结构而引起的。这种异常是编程中常见的
    的头像 发表于 01-12 16:03 4855次阅读

    Service层的异常处理

    一般初学者学习编码和[错误处理]时,先知道[编程语言]有一种处理错误的形式或约定(如Java就抛异常),然后就开始用这些工具。但却忽视这问题本质:「处理错误是为了写正确程序」 。
    的头像 发表于 01-08 11:29 533次阅读

    机械制图常见错误汇总

    今天分享是《机械制图常见错误》 资料。
    的头像 发表于 12-26 10:41 888次阅读
    机械制图常见<b class='flag-5'>错误</b><b class='flag-5'>汇总</b>

    PLC可编程逻辑控制器的常见错误类型以及修复方法/PLC指示灯异常闪烁可能是哪些原因造成的?

    PLC(可编程逻辑控制器)常见的错误类型包括: 1.程序错误:PLC程序编写不正确或存在无法识别的编程语句,导致程序执行出错。 2.硬件故障:PLC设备本身出现问题,如I/O模块故障、CPU出现异常
    的头像 发表于 12-15 11:37 2565次阅读

    AD7779 MEMMAP_CRC_ERR错误异常置位怎么解决?

    , OR = 10KHz),芯片输出异常,读GEN_ERR_REG1发现毫毫米_ crc_ err位异常被置位。若屏蔽该错误似乎不会对采集造成影响。
    发表于 12-07 06:02

    python写错了怎么更改

    要更改Python代码中的错误,你可以按照以下步骤进行: 1.理解错误:首先,你需要仔细阅读错误消息和追踪栈。错误消息通常会提供关于发生
    的头像 发表于 11-29 17:01 1958次阅读

    python缩进错误怎么办

    缩进错误Python编程中常见的错误之一,通常是由于代码块的缩进不正确导致的。Python是一种强制缩进的语言,代码块之间需要保持一致的缩进程度。 缩进
    的头像 发表于 11-29 16:43 2152次阅读

    python运行完后为什么会闪退

    终止。这可能是由于多种原因引起的,下面我将详细介绍几种常见的闪退原因和解决方法。 语法错误:在编写Python代码时,如果有语法错误,程序将无法正确解释和执行代码,从而导致闪退。这些错误
    的头像 发表于 11-29 15:14 8531次阅读

    python运行程序出现红色空白

    当你运行Python程序时,如果出现红色空白,这通常意味着有一个错误发生了。这个错误可能是由多种原因造成的,本文将详细介绍可能的原因和解决方法,帮助你解决这个问题。 语法错误
    的头像 发表于 11-28 15:30 1839次阅读

    python循环里的输出结果汇总

    循环是计算机编程中常用的一种控制结构,用于重复执行一段代码。Python提供了多种类型的循环结构,包括for循环和while循环。在这篇文章中,我们将详细介绍Python循环中的输出结果。 首先
    的头像 发表于 11-22 09:59 1573次阅读