0xf

日記だよ

contextmanagerを利用してアクセス方法だけを隠蔽する

そういえば pythonwith 構文があって、かつタプルの多重代入がいけるのでこのように書けるのだった。

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"))