with open為什麼會自動關閉檔案流

昀溪發表於2018-12-09

操作檔案我們通常需要手動關閉檔案流,可是透過with open()的時候卻可以自動關閉,這是為什麼呢?其實這就是上下文管理器。我們來看一個例子

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
你是否想過一個問題,開啟檔案會丟擲異常,通常開啟檔案後也需要關閉檔案流,為什麼用 with open()語句可以不用手動關閉檔案流呢?
這就是上下文管理器
"""

class Sample:

    def __init__(self):
        # 首先執行這個方法
        print("__init__")

    def __enter__(self):
        # 然後會自動呼叫這個方法,可以理解為獲取資源
        print("__enter__")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # 這個函式會自動呼叫,當跳出with語句的時候,目的是為了釋放資源
        print("__exit__")

    def toDo(self):
        print("to do something")

"""
__enter__和__exit__構成了上下文管理器
"""
# 這個用法是不是很像 with open()呢?
with Sample() as sample:
    print("aaa")

這個上下文管理器還可以簡化一下

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
如何把上下文管理器更加簡化一下呢?
"""

import contextlib

@contextlib.contextmanager # 這個裝飾器把下面的函式包裝成上下文管理器,主要利用了yiele的特性
def myFun(arg1):
    print("begin", arg1)  # 相當於 __enter__ 裡面的程式碼
    yield {}  # 這裡必須有個生成器
    print("finished")  # 相當於 __exit__ 裡面的程式碼


with myFun("AAA") as my:
    print("BBB")

相關文章