最近、同僚が働いているので、キャッシングデコレータを4行で書くことは不可能であると彼らは主張しました。私はそれが可能であると主張しました。それはすべて4行で始まり、1行に一連のラムダ式と1行にデコレータを使用した関数型プログラミングで終わりました。
免責事項
このようなコードは、私のプロジェクトや私のチームのプロジェクトには含まれていません。以下に説明するものはすべて、学術研究の一環として作成されたものです。Pythonプログラミング言語の重要な利点は、その読みやすさであることを理解しています。精神を変える物質の著者は、この記事を書くときにコーヒーだけを使用しました。
プロローグ
当初、4行でデコレータを書くというアイデアは私には触れませんでした。デコレータを書くのはとても楽しかったです。しかし、その過程で、スポーツへの関心が広まりました。それはすべて、単純なキャッシュデコレータから始まりました。
data = {} #
def decor_cache(func):
def wrapper(*args):
#
#
key = f"{func.__name__}{args}"
#
if args in data:
return data.get(key)
else:
#
response = func(args) #
data[key] = response #
return response
return wrapper
ここで、18行のコードのタスクです。スペースとコメントを削除すると11行になり、4行になります。最初に頭に浮かぶのは、if…else構文を1行で書くことです。
data = {} #
def decor_cache(func):
def wrapper(*args):
#
#
key = f"{func.__name__}{args}"
if not args in data
#
response = func(args) #
data[key] = response #
return data.get(key) if args in data else response
return wrapper
これで、18行に対して15行のコードがあり、表示された場合は別のコードが追加の計算負荷を作成しますが、今日はパフォーマンスを向上させるつもりはありません。この世界にエントロピーとコピー&ペーストを追加して、キー変数を単純化してみましょう。
data = {} #
def decor_cache(func):
def wrapper(*args):
if not args in data
#
response = func(args) #
data[f"{func.__name__}{args}"] = response #
return data.get(f"{func.__name__}{args}") if args in data else response
return wrapper
12 , 8 . , 4 , . — callable (). lambda! wrapper lambda — . "", .
data = {} #
def decor_cache(func):
cache = labda *args: data.get(f"{func.__name__}{args}") if args in data else data[f"{func.__name__}{args}"] = func(args)
return labda *args: cache(*args) if cache(*args) else data.get(f"{func.__name__}{args}")
! 4 , — . lambda , lambda . lambda : .
lambda . lambda lambda , , lambda , lambda .
, , — lambda . , . . . - lambda . lambda .
, or. , , True False. . python . memory.update({f"{func.name}_{args[0]}": func(args[0])}) None update None False , memory. tupla, , tuple .
data = {} #
def decor_cache(func):
return lambda *args: memory.get(f"{func.__name__}_{args[0]}") if f"{func.__name__}_{args[0]}" in memory else (lambda: memory.update({f"{func.__name__}_{args[0]}": func(args[0])}) or args[0])()
, lambda . , decorator_cache, lambda , .
data = {} #
decor_cache = lambda func: lambda *args: memory.get(f"{func.__name__}_{args[0]}") if f"{func.__name__}_{args[0]}" in memory else (lambda: memory.update({f"{func.__name__}_{args[0]}": func(args[0])}) or args[0])()
, , . , data. ... 10 , python globals().
globals() , . ( — , — ). , . , :
globals().update({“memory”: {}})
get:
globals().get(“memory”)
, .
decor_cache = lambda func: lambda *args: globals().get("memory").get(f"{func.__name__}_{args[0]}") if f"{func.__name__}_{args[0]}" in globals().get("memory") else (lambda : globals().get("memory").update({f"{func.__name__}_{args[0]}": func(args[0])}) or args[0])()
, . , , , lambda , .
. , . . , , .
, lambda .