python 异常处理

A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in thetry clause and has not been handled by anexcept clause (or it has occurred in aexcept orelse clause), it is re-raised after thefinally clause has been executed. Thefinally clause is also executed “on the way out” when any other clause of thetry statement is left via abreak,continue orreturn statement. A more complicated example (havingexcept andfinally clauses in the sametry statement works as of Python 2.5):

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print "division by zero!"
...     else:
...         print "result is", result
...     finally:
...         print "executing finally clause"
...
>>> divide(2, 1)
result is 2
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

As you can see, the finally clause is executed in any event. TheTypeError raised by dividing two strings is not handled by theexcept clause and therefore re-raised after thefinally clause has been executed.

In real world applications, the finally clause is useful for releasing external resources (such as files or network connections), regardless of whether the use of the resource was successful.

8.7. Predefined Clean-up Actions

Some objects define standard clean-up actions to be undertaken when the object is no longer needed, regardless of whether or not the operation using the object succeeded or failed. Look at the following example, which tries to open a file and print its contents to the screen.

for line in open("myfile.txt"):
    print line

The problem with this code is that it leaves the file open for an indeterminate amount of time after the code has finished executing. This is not an issue in simple scripts, but can be a problem for larger applications. Thewith statement allows objects like files to be used in a way that ensures they are always cleaned up promptly and correctly.

with open("myfile.txt") as f:
    for line in f:
        print line

After the statement is executed, the file f is always closed, even if a problem was encountered while processing the lines. Other objects which provide predefined clean-up actions will indicate this in their documentation.

 

=====================================with的用法===============================================

01.>>> class A:  
02.    def __enter__(self):  
03.        print 'in enter'  
04.    def __exit__(self, e_t, e_v, t_b):  
05.        print 'in exit'  
06.  
07.>>> with A() as a:  
08.    print 'in with'  
09.  
10.in enter  
11.in with  
12.in exit 


 

with从Python 2.5就有,需要from __future__ import with_statement。自python 2.6开始,成为默认关键字。
      也就是说with是一个控制流语句,跟if/for/while/try之类的是一类的,with可以用来简化try finally代码,看起来可以比try finally更清晰。
这里新引入了一个"上下文管理协议"context management protocol,实现方法是为一个类定义__enter__和__exit__两个函数。
      with expresion as variable的执行过程是,首先执行__enter__函数,它的返回值会赋给as后面的variable,想让它返回什么就返回什么,只要你知道怎么处理就可以了,如果不写as variable,返回值会被忽略。
     然后,开始执行with-block中的语句,不论成功失败(比如发生异常、错误,设置sys.exit()),在with-block执行完成后,会执行__exit__函数。
    这样的过程其实等价于:

try:
      执行 __enter__的内容
      执行 with_block.
finally:
      执行 __exit__内容

       只不过,现在把一部分代码封装成了__enter__函数,清理代码封装成__exit__函数。
      我们可以自己实现一个例子:

import sys
class test:
def __enter__(self):
       print("enter")
       return 1
def __exit__(self,*args):
       print("exit")
       return True
with test() as t:
print("t is not the result of test(), it is __enter__ returned")
print("t is 1, yes, it is {0}".format(t))
raise NameError("Hi there")
sys.exit()
print("Never here")

注意:
       1、t不是test()的值,test()返回的是"context manager object",是给with用的。t获得的是__enter__函数的返回值,这是with拿到test()的对象执行之后的结果。t的值是1.

       2、__exit__函数的返回值用来指示with-block部分发生的异常是否要re-raise,如果返回False,则会re-raise with-block的异常,如果返回True,则就像什么都没发生。

原文地址

一 with

python中的with的作用是自动释放对象,即使对象在使用的过程中有异常抛出。可以使用with的类型必须实现__enter__ __exit__。我的理解是=try...finally{},在finally中调用了释放函数。

[类似与CSharp中的using(){}关键字,用来自动确保调用对象的dispose()方法,即使对象有异常抛出。C#中可以使用using{}的对象必须已经实现了IDispose接口。]

 

复制代码
def  TestWith():
  with open(
" myfile.txt " ) as f:
     
for  line  in  f:
         
print  (line)
  f.readline() 
# f is already clean up here, here will meet ValueError exception
   
TestWith()
复制代码

 

在with语句执行完以后,f对象马上就被释放了。所以下面在调用f.readline()会出错。

 

二 with + try...except

既能让对象自动释放,又包含了异常捕获的功能。

复制代码
class  controlled_execution(object):
    
def   __init__ (self, filename):
        self.filename 
=  filename
        self.f 
=  None

    
def   __enter__ (self):
        
try :
            f 
=  open(self.filename,  ' r ' )
            content 
=  f.read()
            
return  content
        
except  IOError  as e:
            
print  (e)

    
def   __exit__ (self, type, value, traceback):
        
if  self.f:
            
print  ( ' type:%s, value:%s, traceback:%s '   %  (str(type), str(value), str(traceback)))
            self.f.close()

def  TestWithAndException():
    with controlled_execution(
" myfile.txt " ) as thing:
        
if  thing:
            
print (thing)

# TestWithAndException()

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值