python with as語法

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()



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章