実用的ではないPython-1行でデコレータを書く

最近、同僚が働いているので、キャッシングデコレータを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 .








All Articles