Recently, with a colleague at work, they argued that it is impossible to write a caching decorator in 4 lines, I argued that it is possible. It all started with 4 lines, ended with functional programming with a bunch of lambda expressions in one line and a decorator in one line.
Disclaimer
Such code does not end up in my projects or my team's projects, and everything described below was written as part of an academic study. I understand that an important advantage of the python programming language is its readability. The author, of the mind-altering substances, used only coffee when writing this post.
Prologue
Initially, the idea of ββwriting a decorator in 4 lines did not bother me in any way. It was just fun to write a decorator. But in the process, sports interest prevailed. It all started with a simple cache decorator.
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
Now a task of 18 lines of code, 11 if you remove spaces and comments, make 4 lines. The first thing that comes to mind is to write the if⦠else construction in one line.
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
15 18, if, , performance. copy-paste key.
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 .