歡迎光臨
每天分享高質量文章

簡單理解 with 背景關係管理器

(點選上方公眾號,可快速關註一起學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萬分謹慎的收起了錢包

這隻是一個建立背景關係管理器的方法,大家記住格式就行。

    贊(0)

    分享創造快樂