1. 程式人生 > >Python學習筆記(五)-- 上下文管理器(Context Manager)

Python學習筆記(五)-- 上下文管理器(Context Manager)

1.定義

寫程式碼時,我們希望把一些操作放到一個程式碼塊中,這樣在程式碼塊中執行時就可以保持在某種執行狀態,而當離開該程式碼塊時就執行另一個操作,結束當前狀態;所以,簡單來說,上下文管理器的目的就是規定物件的使用範圍,如果超出範圍就採取“處理”。
這一功能是在Python2.5之後引進的,它的優勢在於可以使得你的程式碼更具可讀性,且不容易出錯。

2.如何使用

首先我們來看一段未使用上下文管理器的程式碼,看看它在執行過程中會出現什麼問題?

#when without using context manager
f = open("hl.txt"
, "w") print(f.closed) #執行到這裡,會打印出False,因為沒有關閉 f.write("Hello,context manager!") f.close() print(f.closed) #這裡才會打印出True,表示檔案關閉

表面上看似這段程式碼也並沒什麼大的問題,但是仔細想想,你會發現,如果這段程式碼根本執行不到f.close()這一句呢,是不是就出現問題了,假設我們在寫入的過程中,磁碟滿了,程式碼就會在寫入的那一句出現異常,這樣就永遠執行不到f.close()這一句,檔案就永遠不會被關閉,可能你會說我可以用try…finally語句啊,不就解決這個問題了麼,但是同樣會有問題在裡面。
問題就在於,當我們執行的不是簡單的寫入操作,而是其他更復雜的操作,如拷貝,同時讀和寫,這時你會看到try…finally語句根本無法保證程式碼的美感,簡直太糟糕。。所以,上下文管理器就派上用場了,它可以保證不論何時,你的程式碼都是美觀的且安全的。
下面,讓我們來看一下使用了上下文管理器的情況,會是什麼樣子的?

#when using context manager
with open("hl.txt","w") as f:
    print(f.closed)  #False
    f.write("Hello,context manager!")
print(f.closed)  #True 無需執行f.close()

上面程式碼中,可以看到一個程式碼塊:with…as…
其中,with關鍵詞總是伴隨著上下文管理器出現,as關鍵詞將open(“hl.txt”,”w”)賦給了新的物件f,使得在該程式碼塊中可以對f執行任意操作,程式碼相當簡潔。

3.如何建立

想要作為上下文管理器,還需要做一些工作,即需要實現兩個方法:_enter_

()和_exit_();
_enter_():負責進入程式碼塊的準備工作,進入前被呼叫;
_exit_():負責離開程式碼塊的善後工作,離開後被呼叫;

class MyCM(object):
    def __init__(self,text):
        self.text = text
    def __enter__(self):
        self.text = "Enter:" + self.text
        return self
    def __exit__(self,exc_type,exc_value,traceback):
        self.text = self.text + " exit now..."
with MyCM("Context Manager") as mycm:
    print(mycm.text)
print(mycm.text)

列印結果:
Enter:Context Manager
Enter:Context Manager exit now…
任何定義了_enter_()和_exit_()方法的物件都可以用於上下文管理器。