Зачем нужна строка в этой функции Python? (запоминаемая рекурсия) - PullRequest
12 голосов
/ 17 декабря 2011

Я получил следующий фрагмент кода с сайта Питера Норвиг; это декоратор для включения запоминания вызовов функций (кэширование предыдущих вызовов функции для преобразования экспоненциальной рекурсии в простую динамическую программу).

def memo(f):
    table = {}
    def fmemo(*args):
        if args not in table:
            table[args] = f(*args)
        return table[args]
    fmemo.memo = table
    return fmemo

Код работает нормально, но мне интересно, зачем нужна вторая до последней строки. Это явно пробел в моих знаниях Python, но, удалив строку и запустив простую функцию Фибоначчи, она все еще работает. Связано ли это с запоминанием нескольких функций одновременно? Почему переменную-член fmemo можно назвать memo (если это не случайное совпадение)?

Спасибо!

1 Ответ

12 голосов
/ 17 декабря 2011

Поскольку функции являются объектами, как и все остальное, вы можете устанавливать для них атрибуты.См .:

>>> def foo(): pass
>>> foo.x = 1
>>> foo.x
1

Секунда в строку устанавливает внутренний кэш значений в качестве атрибута объекта-функции, тем самым раскрывая его.Это означает, что вы можете взять запомненную функцию и возиться с ее кешем, как вам угодно, без необходимости ее вызова.Это может быть удобно.


Пример:

>>> @memo
... def id(x): return x
>>> id(1)
1
>>> id(2)
2
>>> id.memo
{(2,): 2, (1,): 1}
...