Not practical python - writing a decorator in one line

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 .








All Articles