私のコードでは、デバイスを適切に開いたり閉じたりできる必要があるため、コンテキスト マネージャーを使用する必要があることがわかります。__enter__
コンテキスト マネージャーは通常、とメソッドを持つクラスとして定義され__exit__
ますが、コンテキスト マネージャーで使用するために関数を装飾する可能性もあるようです (最近の投稿と別の良い例を参照してください ここ)。
次の (動作中の) コード スニペットでは、2 つの可能性を実装しています。コメント行を別の行と交換するだけです。
import time
import contextlib
def device():
return 42
@contextlib.contextmanager
def wrap():
print("open")
yield device
print("close")
return
class Wrap(object):
def __enter__(self):
print("open")
return device
def __exit__(self, type, value, traceback):
print("close")
#with wrap() as mydevice:
with Wrap() as mydevice:
while True:
time.sleep(1)
print mydevice()
私が試しているのは、コードを実行して で停止することCTRL-C
です。Wrap
コンテキストマネージャーでクラスを使用すると、__exit__
メソッドは期待どおりに呼び出されます (端末にテキスト「close」が出力されます)が、wrap
関数で同じことを試みると、テキスト「close」が出力されませんターミナル。
私の質問: コード スニペットに問題がありますか、何か不足していますか、それともprint("close")
装飾された関数で行が呼び出されないのはなぜですか?