Python tidak praktis - menulis dekorator dalam satu baris

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 .








All Articles