そういえば python は with
構文があって、かつタプルの多重代入がいけるのでこのように書けるのだった。
from contextlib import contextmanager @contextmanager def create_accessor(): print("before") try: tmp = {} def getter(k): return tmp[k] def setter(k,v): tmp[k] = v yield (getter, setter) finally: print("after") with create_accessor() as (get_value, set_value): set_value("name", "hello") print(get_value("name"))
with
の構文、このケースみたいに前処理後処理を必要としなくても、処理結果を後置で代入してスコープを絞ってアクセスしたい、説明的な記述になって割と好きです。
user = create_user() login(user)
より
with create_user() as user: login(user)
の方が見た目が好きというだけのことではある。
ただ型ヒントがうまく効かないのでそこがネック気味・・・と思っていたら python 3.10.6で以下の記述で型ヒントがいい感じに機能して推論が成功した。
@contextmanager def create_accessor(): print("before") try: tmp = {} def getter(k: str) -> str: return tmp[k] def setter(k:str ,v: str) -> None: tmp[k] = v yield (getter, setter) finally: print("after") with create_accessor() as (get_value, set_value): # (variable) get_value: (k: str) -> str, (variable) set_value: (k: str, v: str) -> None になってる! set_value("name", "hello") print(get_value("name"))