python可能导致异常的代码_Python异常处理

1.理解异常以及错误处理。

2.会用try语句对可能引发异常的代码进行定界。

3.学会raise异常。

4.会用except子句指定异常处理程序。

5.会用finally子句释放资源。

6.理解python异常类层次结构。

7.理解python的跟踪机制。

8.会创建程序员自定义的异常。

异常处理

问题可能发生,但发生得并不频繁。这种特殊事件通常是一个错误(例如除以0,或者对两个不兼容的类型求和);

但有时,特殊事件可能是别的情况(例如for循环终止)。通过异常处理,应用程序能处理(或解决)异常。许多

时候,进行异常处理的程序可继续执行,好象没有发生过问题。.......

python中异常处理的样式以及细节基于Modula-3语言创始人的工作,它类似c#和java中的机制。

程序通常会在执行期间请求和释放“资源”(比如磁盘文件)。通常,这些资源的供应有限,或者

一次只能供一个程序使用。针对这个问题,我们将演示异常处理机制中相应的那一部分功能,既

让一个程序使用资源,然后保证该程序能释放在月微秒年 ,以供其他程序使用。

1。引发异常。

要想引发异常,最简单的形式就是输入关键字raise,后跟要印发的异常的名称。异常名称标识出具体的类;

python异常是那些类的对象。执行raise语句时,python会创建指定的异常类的一个对象。raise语句还可指

定对异常对象进行初始化的对象。为此,请在异常类的名称后添加一个逗号以及指定的参数(或者由参数构

成的一个元祖)。程序可根据异常对象的属性来获得与异常有关的更多信息。raise语句具有多种形式。

......

2。异常处理

程序逻辑经常要检测各种条件,

执行一个任务

如果上一个任务未能正确执行

执行错误处理

执行下一个任务

如果上一个任务未能正确执行

执行错误处理

...

伪代码首先执行一个任务,再检测该任务是否正确执行。如果不是,就执行错误处理。

否则,伪代码将继续下一个任务。尽管这种形式的错误处理也许行的通,但将程序逻辑

和错误处理逻辑混合到一起,会使用程序难以阅读、修改、维护和调试--尤其是在大型

应用程序中。事实上,如果存在许多发生频率并不高的潜在问题,将程序逻辑和错误处

理混在一起会妨碍程序性能,因为程序必须不断测试附加条件,才能判断出是否能执行

下一个任务。

通过异常处理,程序员可将异常处理代码从程序的执行流程中分离出来。这样,程

序结构会变得更加清楚,而且更容易修改。程序员可自行决定对那些异常进行处理。可

选择处理所有类型的异常、特性类型的所有异常,或者一组相关类型的所有异常。这样

的灵活性减少了错误被忽视的可能,所以增强了程序的可靠性。

[[[[[程序员必须将异常处理策略考虑到软件项目中]]]]]]

Example:

########Simple exception handing example########

number1 = raw_input("Enter numerator:")

number2 = raw_input("Enter denominator:")

try:

number1 = float(number1)

number2 = float(number2)

result = number1/number2

except ValueError:

print "You must enter two numbers"

except ZeroDivisionError:

print "Attempted to divide by zero"

else:

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

3.Python的Exception层次结构

python中的几个异常类。所有异常都从基类Exception继承,而且都在exceptions模块中定义。

python自动将所有异常异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可

使用异常。python定义了从Exception继承的4个主要的类,包括SystemExit,StopIteration,

Warning以及StandardError。其中,一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。

如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。python使用StopIteration

异常来判断一个for循环何时抵达序列末尾。Warning异常指出python的一个特定元素将来可能改变。

例如,假定一个python2.2程序中使用了名为yield的一个变量,那么python会印发一个warning异常

,因此在phtyhon未来的该本中,以将yield定义为关键字。StandardError则是所有python“错误”异常

(比如ValueError和ZeroDivsionError)的一个基类。

Exception+

|

-----SystemExit[没有捕捉到该异常,程序直接停止]

|

-----StopIteration[判断一个for循环何时抵达序列末尾]

|

-----Warning[警告]

|

-----StandradError[所有错误异常的基类]

对于任何python,都可以用以下语句显示该结构:

------------------------------

| import exceptions          |

| print exceptions.__doc__   |

------------------------------

但是如果并不清楚异常发生了什么使用:

-------------------

|except Exception:|

-------------------

4.finally子句

程序经常动态地(也就是在执行时)请求和释放资源。例如,从硬盘上读取一个文件的程序会

请求打开那个文件。如果请求成功,就能读取文件内容。操作系统通常会阻止多个程序同时操作同

一个文件。因此,当程序结束处理文件时,程序通常会关闭文件(也就是释放资源),以便其他程

序能使用这个文件。关闭文件有助于避免"资源泄露"(即文件资源无法给其他程序使用,因为原来使

用该文件的程序一直没有关闭)。获得特定类型资源(如文件)的程序必须将资源明确还给系统,以

避免资源泄露。

在c和c++等语言中,程序员要自己负责动态内存管理,一种最常见的资源泄露是”内存泄露“。

如果程序分配(获取)了内存,但在不需要之后没有解释分配(回收),就会发生这种情况。不过在

python中,这通常不是一个问题,因为解释器会对现在正在执行的程序不需要的内存进行”垃圾回收“。

但是在python中有可能发生其他类型的资源泄露(比如前面提到的未关闭的文件)。

对于要求明确释放的大多数资源来说,往往存在一些与资源处理相关的异常。例如,一个文件处理

程序可能在处理期间引发IOError异常。因此,文件处理代码通常放在一个try suite中。无论程序

是否成功处理文件,一旦不需要文件,都应将其关闭。

假定程序将所有资源请求和释放代码都放在一个try suite中。如果没有发生异常,try suite会

正常执行并释放资源。但是,如果发生异常,try suite会在资源释放代码执行之前”过期“。

虽然可在except处理程序中复制所有资源放代码,但这样会使用代码难以修改和维护。

python异常处理机制提供了finally子句,只要程序控制进入了响应的try suite,就必须会这个字句

(无论try suite是成功执行,还是发生异常)。所以,对于在相应try suite中获取和处理的资源,

finally suite是放置资源回收代码的理想地点。如果try suite成功执行,finally suite会在try

suite终止后立即执行。如果在try suite中发生异常,那么在导致异常的那一行之后,会立即执行

finally suite。然后,由下一个封闭的try语句(如果有的话)来处理异常。

######### Using finally clauses#######

def doNotRaiseException():

try:

print "In doNotRaiseException."

finally:

print "Finally exceuted in doNotRaiseException"

print "End of doNotRaiseException"

def raiseExceptionDoNotCatch():

try:

print "In raiseExceptionDoNotCatch"

raise Exception

finally:

print "Finally executed in raiseExceptionDoNotCatch"

print "Will never reach this point"

print "Calling doNotRaiseException"

doNotRaiseException()

print "\nCalling raiseExceptionDoNotCatch"

try:

raiseExceptionDoNotCatch()

except Exception:

print "Caught exception from raiseExceptionDoNotCath"+\

"in main program."

------------------------------------------------------------------------------

|常见变成错误:在finally suite中引发异常是非常危险的。执行finally suite时。  |

|假如一个未被捕捉的异常正在等候处理,而finally suite又引发一个新的,未被该   |

|suite捕捉的异常,那么第一个异常就会丢失,新异常则传递给下一个封闭的try语句。|

------------------------------------------------------------------------------

------------------------------------------------------------------------------

|如果try语句指定了一个finally子句,那么即使try suite由一个return语句终止,   |

| finally子句的suite也会执行执行完之后,才论到通过return返回调用代码。       |

------------------------------------------------------------------------------

......

6.Exception对象和跟踪

从Exception类派生的异常数据类型可用0个或多个参数创建。这些参数常常用于为一个引发的异常格式化错误

提示消息。只要python为了响应一个raise语句而创建一个异常对象,就会将来自raise语句的任何参数放到异

常对象args属性中。

发生异常时,python能”记住“引发的异常以及程序的当前状态。python还维护着traceback(跟踪)对象,

其中含有异常发生时与函数调用堆栈有关的信息。记住,异常可能还在一系列嵌套较深的函数调用中引发。

程序调用每个函数时,python 会在”函数调用堆栈“的起始处插入函数名,一旦异常被引发,python会搜索

到一个响应的异常处理程序。如果当前函数中没有异常处理程序,或者python抵达主程序为止,这一查找

合适的异常处理程序的过程就称为”堆栈辗转开解“(Stack Unwinding)。解释器一方面维护着与放置于

堆栈中的函数有关的信息,另外方面也维护着已从堆栈中”辗转开解"的函数的有关的信息。

#####################

import traceback

def function1():

function2()

def function2():

function3()

def function3():

try:

raise Exception,"An exception as occurred"

except Exception:

print "Caught exception in funtions3.Reraising...\n"

raise #reraise most recent exception

try:

function1()

except Exception,exception:

print "Exception carght in mian program."

print "\nException arguments:",exception.args

print "\nException message:",exception

print "\nTraceback:"

traceback.print_exc()

程序堆栈如下:

function3(顶部)

function2

function1

主程序

换言之,最后一个调用的函数(function3)位于顶部,而主程序位于底部。function3的第16行引发

一个Exception,并将"An exception has occurred"作为参数传递。为响应raise语句,Python使

用指定的参数,创建一个Exception对象。except子句捕捉异常,并将第一个打印出消息。第2行使

用一个空的raise语句“重新引发”异常。重新引发一个异常,通常意味着except处理程序只对异常执

行了局部处理,现在要将异常传回调用者(目前是function2),以便进一步处理。在本例中,

function3在不指定异常名称的前提下,使用关键字raise来重新引发最近引发过的一个异常。

-----------------------------------------------------------------------

|软件工程知识:假如一个函数能处理特定类型的异常,就放手让函数去处理它|

|不要将异常传到程序的另一个区域。                                    |

-----------------------------------------------------------------------

接着,function3终止,因为重新印发的异常未在函数主体中捕获。所以,控制权会返回当初调用

function3的语句(或者调用堆栈中的上一个函数,即function2)。这样会将function3从函数调用

堆栈中删除(或称“辗转开解”),造成函数终止。与此同时,python会创建一个traceback对象,用

它维护来有关函数调用的信息。

控制权返回function2,解释器查明第10行不在一个try suite中。所以,异常无法在function2中捕捉,

这导致function2终止,而且function2也从函数调用堆栈中“展转开解”,并创建另一个traceback对象

(代表当前的辗转开解级别),并将控制权返回function1中的第7行。同样的事情再度发生。第7行不在

一个try suite中,异常无法在function1中捕捉。这导致函数终止,并从调用堆栈中“辗转开解”。与此

同时,创建另一个traceback对象,并使控制权返回至主程序的第24行。由于第24行在try suite中,所以

主程序的try suite会立即“过期”,由第28+行的except处理程序捕捉异常。

....

#######################################################################################

#  说白了就是根据堆栈顺序,如果有异常,捕捉到响应suite即可。不用考虑是否函数体or区域  #

#######################################################################################

测试和调试提示 :阅读traceback报告时,请从下到上顺序,先读错误消息。然后,向上阅读trace

剩余的部分,查找报告中的第一个行号。通常,这就是导致异常的位置。

7。程序自定义异常类

程序员通常可用Python层次结构中现有的异常类来标明程序中发生的异常。但在某些情况下,也可新

建自己的异常类型,使其与程序中发生的问题 严格对应。这种“程序员自定义异常类”应直接或间接

继承于Exception类。

良好的变成习惯:使每类问题都与一个命名得体的异常类关联,使程序结构清晰易读。

###########Demonstating a programmer-defined exception class####

import math

class negativeNumberError(ArithmeticError):

"""Attempted improper operration on nagative number."""

pass

def squareRoot(number):

if number<0:

raise NegativeNumberError,\"Square root of negative number not permitted"

return math.sqrt(nmber)

while 1:

try:

userValue = float(raw_input("\nPlease enter a number:"))

print squareRoot(userValue)

except ValueError:

print "The entered value is not a number"

except NegativeNumberError,exception:

print exception

else:

break;

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2012-10-25 22:41

浏览 2447

评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值