`

Python中的异常处理

 
阅读更多

1.引发异常


在Python中,要想引发异常,最简单的形式就是输入关键字raise,后跟要引发的异常的名称。异常名称标识出具体的类:Python异常是那些类的对象。执行raise语句时,Python会创建指定的异常类的一个对象。raise语句还可指定对异常对象进行初始化的参数。为此,请在异常类的名称后添加一个逗号以及指定的参数(或者由参数构成的一个元组)。

2.异常处理

Python使用try语句实现异常处理。try语句包围着可能引发异常的其他语句。try语句以关键字try开头,后续一个冒号(:)和一个可能在其中引发异常的代码suite。try语句可指定一个或多个except子句,它们紧接在try suite之后。每个except子句都指定了零个或多个异常类名,它们代表要由except子句处理的异常类型。可在except子句中指定一个标志符,程序用它引用被捕捉的异常对象。处理程序利用标识符从异常对象获取也异常有关的信息。如果except子句中没有指定异常类型,就称为"空白except子句"。这种子句会捕捉所有异常类型。在最后一个except子句之后,可选择性地添加一个else子句。如果try suite中的代码没有引发异常,就会执行else子句中的代码。如果try语句没有指定except子句,那就必须包含一个finally子句----该子句肯定会执行,无论是否发生异常。

在try语句中同时包括except和finally子句是语法错误,可接受的组合形式只有:

1 try:
......
except
......

2 try:
......
except
.......
else
......

3 try:
......
finally
........


一旦程序代码导致异常,或Python解释器检测到问题,代码或解释器就会“引发”一个异常。有的程序员将程序中发生异常的位置称为“引发点”。异常是一些类的对象,这些类都是从Exception类继承的。如果在一个try suite中发生异常,这个try suite会立即“超时”(即立即终止),程序控制权会移交给try suite之后的第一个except处理程序(如果有的话),接着解释器搜索可对这种异常类型进行处理的第一个except处理程序。解释器为了确定相匹配的except,需要将引发的异常的类型与每个except处理程序的异常类型比较,直到最终发现相匹配的为止。如类型完全一致,或引发的异常的类型是except处理程序的异常类型的一个派生类,就表明发生了匹配。如果try suite中没有发生异常,解释器将忽略用于try语句的异常处理程序,并执行try语句的else子句(如果有的话)。如果没有发生异常,或者某个except子句成功处理了异常,程序会从try语句之后的下一个语句恢复执行。如果在某个语句中发生了一个异常,但该语句不在一个try suite 中,而是一在一个函数中,那么包含那个语句的函数会立即终止,解释器会试图在(发出)调用(的)代码中查找一个封闭的try语句,这个过程称为“堆栈辗转开解”(Stacking Unwinding)。

3.示例:DivideByZeroError



1 # Fig. 12.1: fig12_01.py
2 # Simple exception handling example.
3
4 number1 = raw_input( "Enter numerator: " )
5 number2 = raw_input( "Enter denominator: " )
6
7 # attempt to convert and divide values
8 try:
9 number1 = float( number1 )
10 number2 = float( number2 )
11 result = number1 / number2
12
13 # float raises a ValueError exception
14 except ValueError:
15 print "You must enter two numbers"
16
17 # division by zero raises a ZeroDivisionError exception
18 except ZeroDivisionError:
19 print "Attempted to divide by zero"
20
21 # else clause

22 print "%.3f / %.3f = %.3f" % ( number1, number2, result )



float函数将用户输入的值转换成浮点值(第9-10行)。如果不能将字符串参数转换成浮点值,该函数就会引发ValueError异常。如果分母为零,第11行将会引发ZeroDivisionError异常。
每个try suite与其第一个except处理程序之间,两个except处理程序之间,最后一个except处理程序和else子句之间或者try suite和finally子句之间,不允许出现任何语句,否则是语法错误。
尽管可在try suite语句中包含任意语句,但通常只包含可能引发异常的语句,在else suite中,则放置不会引发异常,而且只有在相应的try suite中没有发生异常的前提下才就执行的语句。
except处理程序必须指定要捕捉的异常类名,只有针对默认的“全部捕捉”条件,才就使用一个空白的except处理程序。

4.Python的Exception层次结构


Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import exceptions
>>> print exceptions.__doc__
Python's standard exception class hierarchy.

Before Python 1.5, the standard exceptions were all simple string objects.
In Python 1.5, the standard exceptions were converted to classes organized
into a relatively flat hierarchy. String-based standard exceptions were
optional, or used as a fallback if some problem occurred while importing
the exception module. With Python 1.6, optional string-based standard
exceptions were removed (along with the -X command line flag).

The class exceptions were implemented in such a way as to be almost
completely backward compatible. Some tricky uses of IOError could
potentially have broken, but by Python 1.6, all of these should have
been fixed. As of Python 1.6, the class-based standard exceptions are
now implemented in C, and are guaranteed to exist in the Python
interpreter.

Here is a rundown of the class hierarchy. The classes found here are
inserted into both the exceptions module and the `built-in'
module. It is
recommended that user defined class based exceptions be derived from the
`Exception' class, although this is currently not enforced.

Exception
|
+-- SystemExit
+-- StopIteration
+-- StandardError
| |
| +-- KeyboardInterrupt
| +-- ImportError
| +-- EnvironmentError
| | |
| | +-- IOError
| | +-- OSError
| | |
| | +-- WindowsError
| | +-- VMSError
| |
| +-- EOFError
| +-- RuntimeError
| | |
| | +-- NotImplementedError
| |
| +-- NameError
| | |
| | +-- UnboundLocalError
| |
| +-- AttributeError
| +-- SyntaxError
| | |
| | +-- IndentationError
| | |
| | +-- TabError
| |
| +-- TypeError
| +-- AssertionError
| +-- LookupError
| | |
| | +-- IndexError
| | +-- KeyError
| |
| +-- ArithmeticError
| | |
| | +-- OverflowError
| | +-- ZeroDivisionError
| | +-- FloatingPointError
| |
| +-- ValueError
| | |
| | +-- UnicodeError
| | |
| | +-- UnicodeEncodeError
| | +-- UnicodeDecodeError
| | +-- UnicodeTranslateError
| |
| +-- ReferenceError
| +-- SystemError
| +-- MemoryError
|
+---Warning
|
+-- UserWarning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- SyntaxWarning
+-- OverflowWarning
+-- RuntimeWarning
+-- FutureWarning
>>>



如图所示,所有异常都从基类Exception继承,而且都在exceptions模块中定义。Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。Python使用StopIteration异常来判断一个for循环何时抵达序列末尾。Waring异常指定Python的一个特定元素将来可能改变。
异常层次结构的一个优点在于,except处理程序即可捕捉特定类型的异常,也可使用一个基类类型捕捉从它继承的所有类型的异常。
在特定try suite之后,最后一个except之前,设置一个空的except子句属于语法错误。
在特定try suite之后,两个或更多的except子句指定完全相同的异常类型是逻辑错误。Python会执行与引发的异常匹配的第一个except处理程序,忽略其他所有except处理程序。
在其它except处理程序之前,用一个except处理程序捕捉类型为Exception的异常是逻辑错误,因为它会捕捉所有异常,使后面所有异常处理程序形同虚设。

5.finally子句

Python异常处理机制提供了finally子句,只要在程序控制进入相应的try suite,就必然会执行这个子句(无论try suite是成功执行,还是发生异常)。所以,对于在相应try suite中获取和处理的资源,finally suite是放置资源加收代码的理想地点。如果try suite成功执行,finally suite会在try suite终止后立即执行。如果在try suite中发生异常,那么在导致异常的那一行之后,会立即执行finally suite。然后,由下一个封闭的try语句(如果有的话)来处理异常。
finally suite包含的代码一般用于释放相应try块中获得资源,这使finally suite成为消除资源泄露的有效途径。

# Fig. 12.3: fig12_03.py
# Using finally clauses.

def doNotRaiseException():

# try block does not raise any exceptions
try:
print "In doNotRaiseException"

# finally executes because corresponding try executed
finally:
print "Finally executed in doNotRaiseException"

print "End of doNotRaiseException"

def raiseExceptionDoNotCatch():

# raise exception, but do not catch it
try:
print "In raiseExceptionDoNotCatch"
raise Exception

# finally executes because corresponding try executed
finally:
print "Finally executed in raiseExceptionDoNotCatch"

print "Will never reach this point"

# main program

# Case 1: No exceptions occur in called function.
print "Calling doNotRaiseException"
doNotRaiseException()

# Case 2: Exception occurs, but is not handled in called function,
# because no except clauses exist in raiseExceptionDoNotCatch
print "\nCalling raiseExceptionDoNotCatch"

# call raiseExceptionDoNotCatch
try:
raiseExceptionDoNotCatch()

# catch exception from raiseExceptionDoNotCatch
except Exception:
print "Caught exception from raiseExceptionDoNotCatch " + \
"in main program."


在finally suite中引发异常是非常危险的。执行finally suite时,假如一个未被捕捉的异常正在等候处理,而finally suite又引发了一个新的,未被该suite捕捉的异常,那么第一个异常就会丢失,新异常则传递给下一个封闭的try语句。

6.Exception对象和跟踪

发生异常时,Python能“记住”引发的异常以及程序的当前状态。Python还维护着traceback(跟踪)
对象,其中含有异常发生时与函数调用堆栈有关的信息。记住,异常可能在一系列嵌套较深的函数调用中引发。程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名。一旦异常被引发,Python会搜索一个相应的异常处理程序。如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止。这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(Stack Unwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。


# Fig. 12.4: fig12_04.py
# Demonstrating exception arguments and stack unwinding.

import traceback

def function1():
function2()

def function2():
function3()

def function3():

# raise exception, catch exception, reraise exception
try:
raise Exception, "An exception has occurred"
except Exception:
print "Caught exception in function3. Reraising....\n"
raise # reraises most recent exception

# call function1, any Exception it generates will be
# caught by the except clause that follows
try:
function1()

# output exception arguments, string representation of exception,
# and the traceback
except Exception, exception:
print "Exception caught in main program."
print "\nException arguments:", exception.args
print "\nException message:", exception
print "\nTraceback:"
traceback.print_exc()


7.程序自定义异常类


程序员通常可用Python层次结构中现有的异常类来标明程序中发生的异常。但在某些情况下,也可新建自己的异常类型,使其与程序中发生的问题严格对应。这种“程序员自定义异常类”就直接或间接继承于Exception类。


# Fig. 12.5: fig12_05.py
# Demonstrating a programmer-defined exception class.

import math

class NegativeNumberError( ArithmeticError ):
"""Attempted improper operation on negative number."""
pass

def squareRoot( number ):
"""Computes square root of number. Raises NegativeNumberError
if number is less than 0."
""

if number < 0:
raise NegativeNumberError, \
"Square root of negative number not permitted"

return math.sqrt( number )

while 1:

# get user-entered number and compute square root
try:
userValue = float( raw_input( "\nPlease enter a number: " ) )
print squareRoot( userValue )

# float raises ValueError if input is not numerical
except ValueError:
print "The entered value is not a number"

# squareRoot raises NegativeNumberError if number is negative
except NegativeNumberError, exception:
print exception

# successful execution: terminate while loop
else:
break

分享到:
评论

相关推荐

    python——异常处理

    刚开始学习python很不容易理解,python在线教学中异常处理

    python的异常处理.rar

    python的异常处理,异常捕获,try:except:else:finally:

    精品课件-Python常见异常处理.pptx

    Python常见异常处理 精品课件----Python常见异常处理全文共71页,当前为第1页。 理解 掌握 掌握 掌握 学习目标 理解异常的概念 1 2 掌握处理异常的几种方式 掌握raise和assert语句,会抛出自定义的异常 3 4 掌握with...

    Python-异常处理-教学设计.docx

    已学习Python语句的顺序结构和条件分支结构和循环结构,一般程序都可编写,可以学习异常处理这个概念,来对程序编写过程中遇到的问题进行处理,并提高编程技能。 不足之处是对前面所学的知识掌握不够扎实。下图是对...

    关于Python中异常(Exception)的汇总

    python中的异常使用继承结构创建,可以在异常处理程序中捕获基类异常,也可以捕获各种子类异常,python中使用try…except语句捕获异常,异常子句定义在try子句后面。 Python中的异常处理 异常处理的语句结构 try:...

    Python 1 异常处理.doc

    Python 异常处理

    Python异常处理(课件)

    简单介绍Python中的错误和异常,重点介绍Python中的异常处理机制,包括主要的关键字:try、except、finally、else等,以及它们组合使用时程序执行的流程等,非常适合高校老师教学和学生课后复习使用。

    python异常处理.html

    什么是异常处理?什么情况下会发生异常?了解常见异常类,异常处理的语句,try ... except,多个except语句和一个except块

    谷歌COLAB中的Python概念化

    为了满足这一需要,第8章介绍了Python中异常处理的突出特点。第9章介绍了通过文件处理的数据持久性。由于正则表达式在模式匹配中的广泛应用,第10章将完全用于理解Python中的正则表达式。第11章总结了

    Python语言基础:异常处理.pptx

    异常处理 1. try....except结构 语法格式: try: try语句块 #被监控的语句 except内建异常类名: except语句块 #处理异常的语句 异常处理 实例:使用try....except结构编写异常处理的程序,并输出结果。 具体实现: ...

    Python异常处理机制结构实例解析

    首先,Python 完整的异常处理语法结构如下: try: #业务实现代码 except Exception1 as e: #异常处理块1 ... except Exception2 as e: #异常处理块2 ... #可以有多个 except ... else: #正常处理块 finally :...

    python3 与python2 异常处理的区别与联系

    在python2.x中 ,异常是这样的处理的,异常基类后面加一个逗号“ ,” 然后跟着异常类型 import traceback try: 1/0 except Exception , err: print err 在python3.x中,异常是这样处理的,基类通过关键 词”...

    Python异常处理函数和模块学习教案.pptx

    Python异常处理函数和模块学习教案.pptx

    13.1 Python中异常的捕获与处理.mp4

    13.1 Python中异常的捕获与处理.mp4

    Python中的异常处理.xmind

    把可能出现问题的代码,放在try中 把处理异常的代码,放在except中 把必须要执行的代码,放在finally 》》 例如关闭文件流操作

    jmu-python-字符串异常处理.txt

    jmu-python-字符串异常处理.txt

    Python 中常见的异常问题处理

    本文档内容主要探讨 Python 中的异常处理。我们将讨论 try/except,除此之外,我们将学习如何定义自己的 python 异常。 使用 try/except 处理异常 使用 try/except 处理多个异常 try/except 中的 raise 关键字 ...

    python实现拉依达准则处理异常数据

    首先本项目的数据来源于参加的数学建模比赛官方C题提供的相关数据,由于在进行建模和数据分析时,发现预处理的数据存在随机异常性、离散性等不利于模型分析的性质,所以使用了拉依达准则对数据进行处理,而python的...

    Python学习--异常处理思维导图

    Python学习--异常处理思维导图!!来源于网易云课堂王顺子

    Python语言基础:异常.pptx

    如果这些错误得不到正确的处理将会导致程序终止运行,所以本结需要学习Python强大的异常处理机制,合理地使用异常处理可以使程序更加健壮,具有更强的容错性,不会因为错误地输入或运行时遇到的问题而造成程序终止。...

Global site tag (gtag.js) - Google Analytics