Baru-baru ini, dengan seorang kolega di tempat kerja, mereka berpendapat bahwa tidak mungkin untuk menulis dekorator caching dalam 4 baris, saya berpendapat bahwa itu mungkin. Semuanya dimulai dengan 4 baris, diakhiri dengan pemrograman fungsional dengan sekelompok ekspresi lambda dalam satu baris dan dekorator dalam satu baris.
Penolakan
Kode tersebut tidak berakhir di proyek saya atau proyek tim saya, dan semua yang dijelaskan di bawah ini ditulis sebagai bagian dari studi akademis. Saya mengerti bahwa keuntungan penting dari bahasa pemrograman python adalah keterbacaannya. Penulis, dari zat pengubah pikiran, hanya menggunakan kopi saat menulis posting ini.
Prolog
Awalnya, ide menulis dekorator dalam 4 baris tidak menyentuh saya. Itu hanya menyenangkan untuk menulis dekorator. Namun dalam prosesnya, minat olahraga menang. Semuanya dimulai dengan dekorator cache sederhana.
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
Sekarang tugas 18 baris kode, 11 jika Anda menghapus spasi dan komentar, buat 4 baris. Hal pertama yang terlintas dalam pikiran adalah menulis konstruksi ifโฆelse dalam satu baris.
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
Sekarang kami memiliki 15 baris kode melawan 18, dan satu lagi jika muncul, yang menciptakan beban komputasi tambahan, tetapi hari ini kami tidak akan meningkatkan kinerja. Mari tambahkan beberapa entropi dan beberapa copy-paste ke dunia ini dan sederhanakan variabel kuncinya.
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 .