(點選上方公眾號,可快速關註一起學Python)
作者:浪子燕青 連結:
http://www.langzi.fun/深入類與物件-下.html
with背景關係管理器,這個用過很多次,比如在執行mysql陳述句的時候要先連結資料庫,獲取遊標,執行sql陳述句,關閉連線。又或者是文字內容的讀寫,開啟文字寫入內容關閉文字。
如果每次執行一條陳述句都要做這麼多操作,就會產生大量重覆的程式碼,這個時候使用背景關係管理器即可美觀又輕鬆的解決這個問題。
with管理背景關係的作用是對一些重覆的程式碼簡單化,並且能最佳化try/except/finally的寫法。
背景關係的實現是透過兩個魔法函式enter和exit實現,後來更新再造後,使用contextlib提供的API可以更加方便的完成。
概念和功能都明白後,最重要的還是如何實現。
舉個例子:浪子去買貓餅幹,每次買的時候都要做這些動作,掏出錢包,花出x元,收回錢包。每次都要重覆掏錢包收錢包這個動作有些麻煩,並且萬一忘了掏錢包就不能付錢,忘了收錢包的話,錢包就掉了。每次掏錢包收錢包都要寫程式碼,有啥簡介的方式嘛?
使用enter和exit實現(1)
class wallet(object):
def __init__(self,man):
self.man=man
def __enter__(self):
print(self.man + '放心大膽的掏出了錢包')
def __exit__(self, exc_type, exc_val, exc_tb):
print(self.man + '小心翼翼的收起來錢包')
def use_money(man):
return wallet(man)
with use_money('langzi') as a:
print('花了600塊錢')
傳回結果:
langzi放心大膽的掏出了錢包
花了600塊錢
langzi小心翼翼的收起來錢包
使用enter和exit實現(2)
當然也可以這麼寫:
class wallet(object):
def __init__(self,man):
self.man=man
def __enter__(self):
print(self.man + '放心大膽的掏出了錢包')
return self
# return self 這一步非常重要,作用是傳回實體
def __exit__(self, exc_type, exc_val, exc_tb):
print(self.man + '小心翼翼的收起來錢包')
def use_money(self,money):
print(self.man + '花了' + money +'元')
with wallet('浪子')as a:
a.use_money('600')
執行結果:
浪子放心大膽的掏出了錢包
浪子花了600元
浪子小心翼翼的收起來錢包
使用contextlib實現
import contextlib
@contextlib.contextmanager
def use_money(man):
try:
print(man + '十分放心大膽的掏出錢包')
yield None
# yield生成器,執行到這裡會傳回一個值(你隨便寫一個就行)
finally:
print(man + '萬分謹慎的收起了錢包')
with use_money('langzi')as a:
print('花了1塊錢')
傳回結果:
langzi十分放心大膽的掏出錢包
花了1塊錢
langzi萬分謹慎的收起了錢包
這隻是一個建立背景關係管理器的方法,大家記住格式就行。