0

Я пытаюсь реализовать декоратор, который запоминает произвольную функцию. Оказывается, я успешно выполнил это с помощью следующего кода:Разница между декоратором Python с синтаксическим сахаром и без него?

def memoize(func): 
    cache = {} 
    def wrapper(*args, **kwargs): 
     acc = "" 
     for arg in args: 
      acc += str(arg) 
     if acc in cache: 
      return cache[acc] 
     else: 
      cache[acc] = func(*args, **kwargs) 
      return cache[acc] 
    return wrapper 

@memoize 
def fib(n): 
    if n == 0 or n == 1: 
     return 1 
    else: 
     return fib(n - 1) + fib(n - 2) 

Затем fib(100) возвращает 573147844013817084101 довольно быстро. Однако, если я не использую синтаксический сахар:

def fib(n): 
    if n == 0 or n == 1: 
     return 1 
    else: 
     return fib(n - 1) + fib(n - 2) 
memoized = memoize(fib) 
print memoized(100) 

Функция висит. Отлаживая его, похоже, что возвращенная оболочка не может изменить кеш. Может ли кто-нибудь объяснить это поведение? Насколько я знаю, не должно быть разницы между использованием сахара и использованием сахара.

ответ

3

Ваш рекурсивный звонок не сохраняется, поскольку вы использовали новое имя, а не оригинальное имя функции fib. Каждая итерация fib() обращается к fib(), но это назовет оригинальной, неподтвержденной функцией.

Присвоить значение возврата вызова декоратора в fib вместо:

def fib(n): 
    if n == 0 or n == 1: 
     return 1 
    else: 
     return fib(n - 1) + fib(n - 2) 
fib = memoize(fib) 
print fib(100) 

В качестве альтернативы, если вы должны использовать memoize как имя результата декоратора, имеют fib() вызов memoized() для рекурсивных вызовов:

def fib(n): 
    if n == 0 or n == 1: 
     return 1 
    else: 
     return memoized(n - 1) + memoizzed(n - 2) 
memoized = memoized(fib) 
print memoized(100) 

Помните, что синтаксис @decorator присваивает то же имя, а не новое имя. Следующие два эквивалентны:

@memoize 
def fib(n): 
    # .... 

и

def fib(n): 
    # .... 
fib = memoize(fib) # Same name! 

кроме названия fib никогда не привязываются к исходной функции первым.

 Смежные вопросы

  • Нет связанных вопросов^_^