1. 程式人生 > 其它 >如何實現上下文管理器

如何實現上下文管理器

上下文管理器with

首先我們需要了解什麼上下文管理器是做什麼?
以下通過一個例子讓大家明白。

# 例1 常規寫法
fp = open('a.txt')
fp.read()
fp.close()

# 例2 自帶上下文管理器寫法with
with open('a.txt') as fp:
    fp.read()

我們通過以上例子可以看出,

  1. 使程式碼寫的更加簡單了
  2. 實現了檔案的自動關閉,避免了檔案的開啟忘記關閉的現場產生

如何實現自定義一個上下文管理器的方法呢?

1.自定義上下文管理器類
  • 1.需要實現__enter__魔法方法

    此方法主要是在操作之前的前置操作

  • 2.需要實現__exit__魔法方法

    此方法用於操作完成之後的最後收尾

例題:自定義檔案類

class MyFile():
    def __init__(self, path, mode, code='utf-8'):
        self.path = path
        self.mode = mode
        self.code = code

    def __enter__(self):
        self.f = open(self.path, mode=self.mode, encoding=self.code)
        print('成功建立檔案')
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()
        print('成功關閉檔案')


if __name__ == '__main__':
    with MyFile('a.txt', 'wt') as f:
        f.write('abc')
        print(f)
# 輸出結果:
# 成功建立檔案
# <_io.TextIOWrapper name='a.txt' mode='wt' encoding='utf-8'>
# 成功關閉檔案

通過以上例子可以看出:

  1. 上下文管理器,在建立檔案之前,是通過__enter__魔法方法來實現的
  2. 然後在檔案操作執行完成之後,通過__exit__魔法方法自動實現關閉的功能
2.自定義生成器函式+上下文管理器的裝飾方法 生成上下文管理器
  • 首先需要 from contextlib import contextmanager

    匯入contextmanager裝飾器

  • 其次製作一個生成器,然後用該裝飾器去裝飾即可.

    這樣就可以達到製作一個上下文管理器的目的了

from contextlib import contextmanager


@contextmanager
def fun(path, mode, code='utf-8'):
    f = open(path, mode=mode, encoding=code)
    try:
        print('生成檔案了')
        yield f
    finally:
        f.close()
        print('關閉檔案了')


if __name__ == '__main__':
    with fun('b.tat', 'wt') as f:
        f.write('b')
        print(f)
# 輸出結果:
# 生成檔案了
# <_io.TextIOWrapper name='b.tat' mode='wt' encoding='utf-8'>
# 關閉檔案了

通過以上方法可以看出,通過自定義生成器也能製作一個上下文管理器
在try和yield之間 可以寫函式體的功能,finally 實現最後完成之後要做的操作部分!
這樣我們就完成了如何從類和函式來製作上下文管理器!
新人若有寫的不足或者疏漏錯誤的地方,歡迎大家指出,感謝你的觀看!