iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python回顾与整理8:错误和异常
  • 351
分享到

Python回顾与整理8:错误和异常

异常错误Python 2023-01-31 06:01:20 351人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

0.说明        如果想写出用户体验高的代码,那么就需要考虑到在执行自己写的这段代码中在和用户交互的过程中可能会出现的问题,也就是说,需要对可能出现的异常进行处理,只有做好这些工作,才能写出用户体验好的代码。1.什么是异常错误    

0.说明


        如果想写出用户体验高的代码,那么就需要考虑到在执行自己写的这段代码中在和用户交互的过程中可能会出现的问题,也就是说,需要对可能出现的异常进行处理,只有做好这些工作,才能写出用户体验好的代码。




1.什么是异常


  • 错误

        错误是语法(导致解释器无法解释)或逻辑(也就是代码质量问题)上的,在python中,当检测到错误时,解释器会指出当前流无法继续执行下去,于是就出现了异常。

  • 异常

        程序出现了错误而在正常控制流以外采取的行为。

        根据上面的解释,可以理解为,只要解释器检测到程序运行时出现了错误(与Python解释器不相容而导致),就会触发一个异常。




2.Python中的异常


        如下:

异常类型描述简单例子
NameError尝试访问一个未声明的变量,或者是在名称空间中不存在的变量
>>> xpleaf
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'xpleaf' is not defined
ZeroDivisionError除数为零
>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division
 or modulo by zero
SyntaxError

Python解释器语法错误

(唯一不是在运行时发生的异常,发生在编译时,Python解释器无法把相关脚本编译为Python字节代码)

>>> for
  File "<stdin>", line 1
    for
      ^
SyntaxError: invalid syntax
IndexError请求的索引走出序列范围
>>> aList = []
>>> aList[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
KeyError请求一个不存在的字典关键字
>>> aDict = {'name': 'xpleaf', 'love': 'cl'}
>>> aDict['clyyh']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'clyyh'
IOError

输入/输出错误

(任何类型的I/O错误都会引发IOError异常)

>>> f = open('xpleaf')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or 
directory: 'xpleaf'
AttributeError尝试访问未知的对象属性
>>> class myClass(object):
...   pass
... 
>>> myInst = myClass()
>>> myInst.name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'myClass' object has no 
attribute 'name'




3.检测和处理异常


        需要注意的是,这和前面提到的检测和处理错误并不一样,检测和处理错误的结果是会引发一个异常,这是由Python解释器完成的;当然我们也可以人为地触发一个异常,这时开发者会认为,用户对程序的使用是不正确的,所以才引发这样一个异常。

        当异常出现的时候,如果不对该异常进行处理,那么Python解释器就会中止当前程序的运行,因此,我们需要对异常进行处理,以达到即使异常出现了,也不会中止程序的执行。


(1)try-except语句

  • 语法

try:
    try_suite    #监测这里的异常
except Exception[, reason]:
    except_suit    #异常处理代码

        reason是错误原因,由捕获的异常本身带有,只需要定义一个变量即可以对其进行使用。

        打开一个不存在的文件时:

>>> f = open('xpleaf')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'xpleaf'

        其中:

[Errno 2] No such file or directory: 'xpleaf'

        便是错误原因,可以使用try-except语句来处理上面的异常:

>>> try:
...   f = open('xpleaf', 'r')
... except IOError, e:
...   print 'could not open file:', e
... 
could not open file: [Errno 2] No such file or directory: 'xpleaf'

忽略代码,继续执行,向上移交:

指的是,如果该层代码(比如一个函数内)有相关的异常处理器(即except语句),就会跳到该异常处理器中进行处理,后面的代码会被忽略(后面的其它except语句);如果在该层没有找到对应的异常处理器,该异常会被向上移交,比如移交到调用该函数的上层代码;当异常到达最顶层仍然没有找到对应处理器时,就认为这个异常是未处理的,Python解释器会显示出跟踪记录,然后退出。


(2)带有多个except的try语句

  • 语法

try:
    try_suite
except Exception1[, reason1]:
    suite_for_exception_Exception1
except Exception2[, reason2]:
    suite_for_exception_Exception2

        需要注意的是,当有异常发生时,一旦找到对应的异常处理器,程序的执行流就会跳转到该异常处理器中,其它的except语句将会被忽略。


(3)处理多个异常的except语句

  • 语法

try:
    try_suite
except (Exception1, Exception2)[, reason1]:
    suite_for_exception_Exception1_and_Exception2

        需要注意的是,这些不同的异常应该被放入到一个元组中。

拓展:包装内建函数

如下:

>>> def safe_float(obj):
...   try:
...     retval = float(obj)
...   except (ValueError, TypeError):
...     retval = 'argument must be a number or numeric string'
...   return retval

执行如下:

>>> safe_float(123)
123.0
>>> safe_float('123')
123.0
>>> safe_float('foo')
'argument must be a number or numeric string'

这是一种非常不错的技巧,要善于利用。


(4)捕获所有异常


        如果需要捕获所有因错误而引起的异常,可以直接捕获Exception异常,Exception是绝大多数Python内建异常的基类。

        但是对于SystemExit和KeyboardInterupt这两个异常,使用Exception是无法捕获的,因为它们不是Exception的继承者,原因很简单,因为这两个异常不是由于错误条件引起的。SystemExit是由于当前Python应用程序需要退出,KeyboardInterrupt代表用户按下了ctrl-c,想要关闭Python。

        但是这三者都有一个共同的基类,那就是BaseException,也就是这三者在程序结构上是同级的,如下:

BaseException
  -KeyboardInterrupt
  -SystemExit
  -Exception
    -(all other current built-in exceptions)

        因此,如果真的想要捕获所有的异常(包括非错误条件引起的),就可以使用BaseException,可以看下面的例子:

  • 使用Exception:无法捕获KeyboardInterrupt

        代码如下:

try:
    name = raw_input('Your name:')
except Exception:
    print 'quit'

        执行如下:

/usr/bin/python2.7 /home/xpleaf/PyCharmProjects/Python_book/10/test.py
Your name:Traceback (most recent call last):
  File "/home/xpleaf/PycharmProjects/Python_book/10/test.py", line 3, in <module>
    name = raw_input('Your name:')
KeyboardInterrupt
  • 使用BaseException:捕获所有异常(错误与非错误条件引起的)

        代码如下:

try:
    name = raw_input('Your name:')
except BaseException:
    print 'quit'

        执行如下:

/usr/bin/python2.7 /home/xpleaf/PycharmProjects/Python_book/10/test.py
Your name:quit

        这样的好处是,如果需要同时捕获三个同级的异常,使用一个except语句就可以。


        但是需要注意的是,try-except语句是为了更好地跟踪潜在的错误并在代码里准备好处理异常的逻辑,不应该将其作为异常过滤器来捕获所有异常,并忽略掉这些异常。


(5)异常参数

        其实所谓异常参数,对于前面的一个例子,为什么使用e错误原因时,就可以得到与该异常相关的字符串信息呢?那是因为,异常引发后,它传递了一个参数给异常处理器。

        直接看下面一个例子:

>>> try:
...     float('foo')
... except ValueError, e:
...     print 'Error Happen:', e
... 
Error Happen: could not convert string to float: foo
>>> 
>>> type(e)
<type 'exceptions.ValueError'>
>>> str(e)
'could not convert string to float: foo'
>>> print e
could not convert string to float: foo
>>> e.__class__
<type 'exceptions.ValueError'>
>>> e.__class__.__name__
'ValueError'
>>> e
ValueError('could not convert string to float: foo',)

        我们可以得出下面的结论:

  • 异常引发时,如果使用错误原因变量,实际上,这是一个包含来自导致异常的诊断信息的类实例,异常参数自身会组成一个元组,并存储为这个异常类的属性

        在这个例子中的分析是,引发了ValueError异常,然后e就是该异常的一个实例,并且在生成这个实例e的过程中,异常参数('could not convert string to float: foo',)(注意这是一个元组),就会成为e的一个属性,而使用str(e)可以输出诊断信息的字符串,那是因为调用了该类实例的__str__()方法 。

        注意,如果用一个except语句来同时捕获多个异常时,使用一个错误原因即可,因为每一个异常都会生成自己的异常参数。

        再强调:

  • 异常参数是该异常发生时传递给异常处理器的一个字符串对象,它会成为这个异常类的实例的一个属性,并且可以通过调用str()来获得该诊断信息(使用print语句,实际也是调用了该str()方法)

拓展:继续前面的float()例子

代码如下:

def safe_float(object):
    try:
        retval = float(object)
    except (ValueError, TypeError), diag:
        retval = str(diag)
    return retval

result = safe_float('foo')
print result
result2 = safe_float([])
print result2

执行如下:

/usr/bin/python2.7 /home/xpleaf/PycharmProjects/Python_book/10/test.py
could not convert string to float: foo
float() argument must be a string or a number

        PS:更进一步学习,可以考虑参考异常类的源代码。


(6)else子句

        没有捕获到异常时,就执行else子句中的代码块,一个简单的例子如下:

>>> try:
...     float(4)
... except (ValueError, TypeError), e:
...     print 'Error Happen:', e
... else:
...     print 'No Exceptions'
... 
4.0
No Exceptions


(7)finally子句

        即无论异常是否有发生或是否捕捉到异常,都会执行的语句块。

        常用的方式如下:

  • try-except-finally

try:
    A
except Exception1, e:
    B
finally:
    C
  • try-except-else-finally

try:
    A
except Exception1, e:
    B
else:
    C
finally:
    D

        至于书本上说的各种形式上的问题,则可以不用考虑太多,在实践中使用时加以使用把可能出现的情况考虑到就可以了。




4.上下文管理


        try-except和try-finally的一种特定的用法是保证共享的资源的唯一分配,并在任务结束的时候释放它,比如文件、线程资源、简单同步、数据库连接等,以打开文件为例。但其实如果用with语句,会方便很多:

>>> with open('xpleaf.txt', 'r') as f:
...     for eachLine in f:
...         print eachLine
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'xpleaf.txt'

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

        当然这种方法仅适用于支持上下文管理协议的对象。关于上下文管理协议,由于目前还没有使用到,所以暂不做总结




5.字符串作为异常


        知道有这种情况就可以,在实际中仍然使用类异常。




6.触发异常


        使用raise关键字就可以人为地触发各种异常。

  • 语法

raise [SomeException [, args [, traceback]]]

        其用法可以有如下:

raise语句的用法
raise语法描述
raise exclass触发一个异常,从cxclass生成一个实例(不含任何异常参数)
raise exclass()同上,但现在不是类;通过函数调用操作符(其实就是指加上了`()`)作用于类生成一个新的exclass实例,同样也没有异常参数
raise exclass, args同上,但同时提供的异常参数args,可以是一个参数也可以是元组
raise exclass(args)同上
raise exclass, args, tb同上,但提供一个跟踪记录(traceback)对象tb供使用
raise exclass, instance通过实例触发异常(通常是exclass的实例);如果实例是exclass的子类实例,那么这个新异常的类型会是子类的类型(而不是exclass);如果实例既不是exclass的实例也不是exclass子类的实例,那么会复制此实例为异常参数去生成一个新的exclass实例
raise instance
通过实例触发异常:异常类型是实例的类型;等价于raise instance.__class__, instance(同上)
raise重新触发前一个异常,如果之前没有异常,触发TypeError

        对于raise string以及相关的方法,这里就不提及了,因为实际上很少用到,另外对于traceback也不常用。可举例如下:

  • raise exclass

>>> raise ValueError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError
  • raise exclass()

>>> raise ValueError()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError
  • raise exclass, args

>>> raise ValueError, 'Something wrong happen about value'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Something wrong happen about value
>>> 
>>> raise ValueError, ('New Error', 'Something wrong happen about value')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: ('New Error', 'Something wrong happen about value')
  • raise exclass(args)

>>> raise ValueError('Something wrong happen about value')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Something wrong happen about value
  • raise exclass, instance

>>> newError = ValueError('Something wrong happen about value')
>>> raise ValueError, newError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Something wrong happen about value
>>> 
>>> newError = ValueError('Something wrong happen about value')
>>> raise IOError, newError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: Something wrong happen about value
# 注意看异常类型和异常参数
  • raise instance

>>> newError = ValueError('Something wrong happen about value')
>>> raise newError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Something wrong happen about value
>>> 
>>> raise newError.__class__, newError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Something wrong happen about value
  • raise

>>> raise
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType
# 即达不到所描述的效果,即使前面已经有异常出现,还是会触发TypeError异常




7.断言


        断言通过assert语句实现,测试一个表达式,如果返回值是假,触发异常。触发异常时,可以像处理普通异常一样对它进行处理。

  • 语法

assert expression[, arguments]

        举例如下:

>>> assert 1 == 1
>>> assert 1 == 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
>>>
>>> assert 1 == 0, 'One does not equal zero silly!'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: One does not equal zero silly!




8.标准异常


        所有的标准异常都是内建的,所以可以直接在交互器或执行脚本文件时使用,关于Python当前的标准异常集,其实只要查看源代码就可以很清晰地知道有哪些标准异常了,这里就不再列出来了。

        另外,有3个直接从BaseException派生的异常子类:

  • SystemExit

  • KeyboardInterrupt

  • Exception

        其它的所有内建异常都是Exception的子类。




9.创建异常


        其实创建异常,只需要继承一个异常,并根据自己的需要进行定制即可,但由于目前还使用不到,所以先略过,实际上可以通过书上的例子和异常类的源代码来加深对Python面向对象编程的理解,往后再做整理。




10.(现在)为什么用异常


        肯定是需要用异常的,因为需要达到这样的目的:运行环境必须足够强健,来处理应用级别的错误,并提供用户级别的错误信息。这样才能提供良好的用户体验。




11.到底为什么要异常


        没有异常,将会导致很多问题。

        



12.异常和sys模块


        可以通过sys模块中的exc_info()函数来获取异常信息,举例如下:

>>> try:
...     float('abc123')
... except:
...     import sys
...     exc_tuple = sys.exc_info()
... 
>>> print exc_tuple
(<type 'exceptions.ValueError'>, ValueError('could not convert string to float: abc123',), <traceback object at 0x7f9ba0fa0f38>)

        可以看到,从sys.exc_info()中得到一个三元组,元素分别如下:

  • exc_type:异常类

  • exc_value:异常类的实例

  • exc_traceback:跟踪记录对象

        跟踪记录对象提供了发生异常的上下文,包含诸如代码的执行帧,异常发生时的行号等信息。




13.相关模块


        如下:

异常相关的标准库
模块描述
exceptions内建异常(不需要导入这个模块)
contextlib为使用with语句的上下文对象工具
sys主要是sys.exc_info()




--结束END--

本文标题: Python回顾与整理8:错误和异常

本文链接: https://www.lsjlt.com/news/189811.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python回顾与整理8:错误和异常
    0.说明        如果想写出用户体验高的代码,那么就需要考虑到在执行自己写的这段代码中在和用户交互的过程中可能会出现的问题,也就是说,需要对可能出现的异常进行处理,只有做好这些工作,才能写出用户体验好的代码。1.什么是异常错误    ...
    99+
    2023-01-31
    异常 错误 Python
  • Python回顾与整理3:数字
    0.说明             数字用的次数是否多主要是看需求,如果是做自动化运维平台开发,比如做一个自动监控的系统,那么你肯定需要收集一定量的数据,然后再对这些数据做一定的处理,那么这时候,你就一定需要用得上数字的。当然,我这里所说的要...
    99+
    2023-01-31
    数字 Python
  • Python错误与异常处理
    1. 从键盘输入一个整数,求 100 除以它的商,并显示输出。要求对从键盘输入的数值进行异常处理。 try:     n=int(input("请输入一个整数:"))     x=1...
    99+
    2024-04-02
  • python错误和异常
    一:语法错误syntax errors        熟悉语法!二:异常    ①打印错误信息时,异常的类型作为异常的内置名显示,并以调用栈的形式显示具体信息    ②常见的异常:            NameError、       ...
    99+
    2023-01-30
    异常 错误 python
  • python基础之错误和异常处理
    import Exception # except 在捕获错误异常的时候 是要根据具体的错误类型来捕获的 # 用一个块 可以捕获多个不同类型的异常 # EXception ...
    99+
    2024-04-02
  • Java JSP 异常处理:处理错误和异常
    异常处理在 Java 和 JSP 编程中至关重要,因为它允许应用程序优雅地处理错误和异常情况,从而提高健壮性和用户体验。 JSP 中的异常处理 JSP 提供了三种主要机制来处理异常: page 指令:该指令指定处理某个页面上所有未处理异...
    99+
    2024-03-15
    JSP
  • Python异常与错误处理详细讲解
    基础知识 优先使用异常捕获 LBYL(look before you leap): 在执行一个可能出错的操作时,先做一些关键的条件判断,仅当满足条件时才进行操作。 EAFP(eais...
    99+
    2022-12-22
    Python异常 Python错误处理
  • Python 错误和异常小结
    1.Python异常类 Python是面向对象语言,所以程序抛出的异常也是类。常见的Python异常有以下几个,大家只要大致扫一眼,有个映像,等到编程的时候,相信大家肯定会不只一次跟他们照面(除非你不用Python了)。异常描述NameEr...
    99+
    2023-01-31
    小结 异常 错误
  • Python常遇到的错误和异常
    目录1、语法错误2、异常3、异常处理4、try/except...else5、try-finally 语句6、抛出异常7、用户自定义异常在日常的学习Python过程中,由于本身的编程...
    99+
    2024-04-02
  • 再谈PHP错误与异常处理
    目录一、异常与错误的概述PHP中什么是异常PHP中什么是错误上面的说法是有前提条件的PHP异常处理很鸡肋?二、ERROR的级别三、PHP异常处理中的黑科技1:set_error_ha...
    99+
    2024-04-02
  • Python错误和异常总结详细
    目录1、语法错误2、异常3、try...except...语句4、多个except子句5、try...except Exception as e语句6、try...except......
    99+
    2024-04-02
  • PHP 异常处理:对错误和异常的全面处理
    异常处理是 php 中处理错误和异常的重要机制,提高了应用程序的健壮性和稳定性。错误由解释器抛出,表示无法恢复的严重问题。异常由代码抛出,表示可恢复的运行时问题。php 提供了 erro...
    99+
    2024-05-11
    php 异常处理
  • Python基础之(九)错误和异常
    >>> for i in range(10) File "<stdin>", line 1 for i in range(10) ^ SyntaxError:...
    99+
    2023-01-31
    异常 错误 基础
  • php异常和错误处理机制
    文章目录 基本概念标准异常处理自定义异常处理 异常处理最佳使用场景控制异常代码影响范围保证数据统一性 错误处理错误等级定义标准错误处理自主处理非致命错误自主处理致命错误抛出自定义错误 ...
    99+
    2023-09-13
    php
  • Impala如何处理错误和异常
    Impala处理错误和异常的方式有以下几种: 异常处理:Impala会捕获并处理运行时错误和异常,如语法错误、数据类型错误等。当...
    99+
    2024-04-02
  • php常见的错误与异常处理方法
    本篇内容介绍了“php常见的错误与异常处理方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php与其他计算机编程语言在遇到错误就抛出异常不...
    99+
    2023-06-02
  • Pig怎么处理异常和错误
    在Python中,我们通常使用try-except语句来处理异常和错误。try块中包含可能会出现异常的代码,except块中包含处理...
    99+
    2024-04-02
  • Impala怎么处理异常和错误
    Impala处理异常和错误的方式包括以下几种方法: 使用TRY-CATCH语句:在Impala中,可以使用TRY-CATCH语句来...
    99+
    2024-04-02
  • Golang错误处理方式异常与error
    目录一、异常二、错误Go 提供了两种处理错误 方式, 一 种是借助 panic和 recover 的抛出捕获机制, 另一种使用error 错误类型 一、异常 1、go没有try/ca...
    99+
    2023-01-14
    Go异常与error Go异常 Go error
  • SpringBoot中怎么处理错误和异常
    在Spring Boot中,可以通过以下几种方式来处理错误和异常: 使用@ControllerAdvice注解来定义全局异常处理类...
    99+
    2024-04-09
    SpringBoot
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作