Python no es práctico: escribir un decorador en una línea

Recientemente, con un colega en el trabajo, argumentaron que es imposible escribir un decorador de caché en 4 líneas, yo sostuve que es posible. Todo comenzó con 4 líneas, terminó con programación funcional con un montón de expresiones lambda en una línea y un decorador en una línea.





Descargo de responsabilidad

Dicho código no termina en mis proyectos o en los proyectos de mi equipo, y todo lo que se describe a continuación fue escrito como parte de un estudio académico. Entiendo que una ventaja importante del lenguaje de programación Python es su legibilidad. El autor, de las sustancias que alteran la mente, usó solo café al escribir este artículo.





Prólogo

Inicialmente, la idea de escribir un decorador en 4 líneas no me tocó. Fue divertido escribir un decorador. Pero en el proceso, prevaleció el interés por los deportes. Todo comenzó con un simple decorador de caché.





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
      
      



Ahora una tarea de 18 líneas de código, 11 si quita espacios y comentarios, haga 4 líneas. Lo primero que me viene a la mente es escribir la construcción if… else en una línea.





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
      
      



Ahora tenemos 15 líneas de código contra 18, y otra si apareció, lo que crea una carga computacional adicional, pero hoy no vamos a mejorar el rendimiento. Agreguemos algo de entropía y algo de copiar y pegar a este mundo y simplificar la variable clave.





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