實際上,只要物件支援環境管理協定(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='')
for line in file:
print(line, end='')
Reference:
1.http://openhome.cc/Gossip/Python/WithAs.html
沒有留言:
張貼留言