2013年5月14日 星期二

with as語句


實際上,只要物件支援環境管理協定(Context Management Protocol),就可以使用with as語句。支援環境管理協定的物件,必須實作__enter__()__exit__()兩個方法,這樣的物件稱之為環境管理員(Context Manager)

with陳述句一開始執行,就會進行__enter__()方法,該方法傳回的物件,可以使用as指定給變數(如果有的話),接著就執行with區塊中的程式碼。

如果with區塊中的程式碼發生了例外,則會執行__exit__()方法,並傳入三個引數,這三個引數,與 
再看 try、raise中所提到的 
sys.exc_info() 傳回的三個值是相同的,也就是例外的類型、例 外訊息以及traceback物件。此時__exit__()方法若傳回False,則例外會被重新丟出,否則例外就停止傳播,通常__exit__()會傳回False以在with之外還可以處理例外。

如果with區塊中沒有發生例外而執行完畢,則也是執行__exit__()方法,此時__exit__()的三個參數都接收到None

所以,假設你要自行實作一個可以自動關閉檔案的物件,則可以如下:

class FileReader:
    def __init__(self, filename):
        self.filename = filename
    
    def __enter__(self):
        self.file = open(self.filename, 'r', encoding='UTF-8')
        return self.file
    
    def __exit__(self, type, msg, traceback):
        if type:
            print(msg)       # 作你的例外處理
        self.file.close()
        return False

接下來你就可以在FileReader物件上使用with as語句。例如:
with FileReader('demo.py') as file:
    for line in file:
        print(line, end='')


Reference:
1.http://openhome.cc/Gossip/Python/WithAs.html

沒有留言:

張貼留言