2011-12-17 14 views
12

Mam następujący fragment kodu ze strony Petera Norviga; to dekorator, który umożliwia zapamiętywanie w wywołaniach funkcji (buforowanie wcześniejszych wywołań funkcji w celu zmiany wykładniczej rekurencji na prosty program dynamiczny).Dlaczego linia w tej funkcji Pythona jest konieczna? (memoised recursion)

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

Kod działa poprawnie, ale zastanawiam się, dlaczego sekundy do ostatniej linii jest konieczne. Jest to wyraźnie luka w mojej wiedzy na temat Pythona, ale usunięcie linii i uruchomienie prostej funkcji Fibonacci nadal wydaje się działać. Czy ma to związek z zapamiętaniem wielu funkcji jednocześnie? Dlaczego zmienną członkowską fmemo można nazwać memo (zakładając, że nie jest to niezręczny zbieg okoliczności)?

Dzięki!

+0

Wcięcia kodu nie wygląda dobrze. Czy jest to funkcja zagnieżdżona? – MAK

+0

FTFY ........... – katrielalex

+1

BTW zostało to zaimplementowane w Pythonie 3.2 jako ['functools.lru_cache'] (http://docs.python.org/dev/library/functools.html#functools .lru_cache). – katrielalex

Odpowiedz

12

Ponieważ funkcje są obiektami, tak jak wszystko inne, można ustawić atrybuty na nich. Patrz

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

drugiej linii do wyznacza wewnętrzną pamięć wartości jako atrybutu obiektu funkcji, a tym samym naraża je. Oznacza to, że możesz zabrać zapamiętaną funkcję i skrzypić z pamięcią podręczną, jak chcesz, bez konieczności wywoływania tego. To może być wygodne.


Przykład:

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

Dodałbym do tego, że nie jest to * konieczne *, ze względu na zamknięcie. Jak już mówisz, ważna będzie umiejętność mieszania się z nim lub uzyskiwania dostępu do wartości bez konieczności wywoływania tego. –

+0

Rzeczywiście, zamknięta zmienna 'table' również określa pamięć podręczną (która jest rzeczywiście problematyczna, jeśli' memo' jest ponownie przypisana na zewnątrz) ... ale +1. –

+0

Rzeczywiście ponowne przypisanie 'memo' byłoby złe. – katrielalex

Powiązane problemy