2011-12-17 11 views
12

Ho ottenuto il seguente snippet di codice dal sito Web di Peter Norvig; è un decoratore per abilitare la memoizzazione sulle chiamate di funzione (memorizzazione nella cache di chiamate precedenti alla funzione per modificare una ricorsione esponenziale in un semplice programma dinamico).Perché è necessaria una linea in questa funzione python? (ricorsione memoized)

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

Il codice funziona correttamente, ma mi chiedo perché è necessaria la penultima riga. Questo è chiaramente un divario nella mia conoscenza di Python, ma rimuovendo la linea e eseguendo una semplice funzione di Fibonacci, sembra ancora funzionare. Ha a che fare con la memoizzazione di più funzioni contemporaneamente? Perché la variabile membro di fmemo può essere chiamata memo (supponendo che non sia una coincidenza impacciata)?

Grazie!

+0

indentazione del codice non guardare a destra. È una funzione annidata? – MAK

+0

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

+1

BTW questo è stato implementato in Python 3.2 come ['functools.lru_cache'] (http://docs.python.org/dev/library/functools.html#functools .lru_cache). – katrielalex

risposta

12

Poiché le funzioni sono oggetti proprio come qualsiasi altra cosa, è possibile impostare attributi su di esse. Vedi:

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

Il secondo sulla riga imposta la cache interna dei valori come attributo sull'oggetto funzione, esponendolo. Ciò significa che puoi prendere una funzione memorizzata e giocherellare con la cache come vuoi, senza doverla chiamare. Questo potrebbe essere conveniente.


Esempio:

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

Aggiungo a questo che non è * necessario *, a causa della chiusura. Come dici tu, la possibilità di interferire con essa o accedere ai valori senza doverla chiamare sarà la cosa importante. –

+0

In effetti, la variabile 'table' chiusa dice anche la cache (che in realtà è problematica se' memo' viene riassegnato all'esterno) ... ma +1. –

+0

In effetti, la riassegnazione di 'memo' sarebbe negativa. – katrielalex

Problemi correlati