with-独自のコンテキストマネージャを実現

1817 ワード

テキストリンク:https://www.jianshu.com/p/0f4e2babb85d
コンテキストマネージャは、類似のファイル、ネットワーク接続、ロックなどのリソースを管理するプログラムで最もよく使用されます.これらのリソースのキーは、正しく動作するには、明示的に閉じたり解放したりしなければならないことです.コンテキストマネージャを作成するには、with文で定義されたコードブロックにコードを含める必要があるという主な原則があります.オブジェクトがwith文と互換性を持つようにするには、__を実装する必要があります.enter__()と_exit__()メソッド.
ファイルを実装するコンテキストマネージャ
class File(object):

    def __init__(self, file, mode):
        self.file = file
        self.mode = mode

    def __enter__(self):
        self.opened_file = open(self.file, self.mode)
        return self.opened_file

    def __exit__(self, type, value, traceback):
        self.opened_file.close()

#    __enter__() __exit__()   ,    with         
with File('hello.txt', 'w') as f:
    f.write('hello')

内部実装手順:1、with文は先にFileクラスの__を保留したexit__メソッドを呼び出し、Fileクラスの__を呼び出します.enter__方法.2、__enter__メソッドはファイルを開きwith文に戻り、開いたファイルハンドルはopened_に渡されます.fileパラメータ.3、with文呼び出し前に一時保存された_exit__メソッド、_exit__メソッドはファイルを閉じます.
異常処理:1、異常のtype、value、tracebackを__に渡すexit__方法2、それは_exit__異常を処理する方法3、もし_exit__Trueを返すと、この異常は無視されます.4、もし_exit__True以外のものを返すと、この異常はwith文に投げ出されます.
@contextmanagerによるコンテキストマネージャの実装contextlibモジュールの@contextmanagerアクセサリを使用すると、コンパクトなコンテキストマネージャ関数を簡単に作成できます.
from contextlib import contextmanager

@contextmanager
def file(file, mode):
    file = open(file, mode)
    try:
        yield file
    finally:
        file.close()

#   
with file('hello.txt', 'w') as f:
    f.write('hello world!')

file()関数では、yieldより前のすべてのコードがコンテキストマネージャの__として使用されます.enter__()メソッドは実行され、yieldの後にあるすべてのコードは__として使用されます.exit__()メソッドが実行されます.異常が発生した場合、yield文に投げ出されます.
変換元:https://www.jianshu.com/p/0f4e2babb85d参照先:https://www.cnblogs.com/sfencs-hcy/p/10125534.html https://www.cnblogs.com/huchong/p/8268765.html