Python - Funzione cache e decoratore

0

Sto giocando con le funzioni cache usando decoratori.

Per prima cosa, uso una funzione generica

def memorize(func):
    cache = {}
    print "printing cache"
    print cache
    print "cache printed"    
    def decor_func(*args):
        if args in cache:
            print "cached value is found"
            return cache[args]
        else:
            print "calculating the value"
            val = func(*args)
            cache[args] = val
            return val
    return decor_func

Quindi lo uso per decorare una funzione chiamata test

def test(n):
    return n

test_decorated = memorize(test)

Quindi ottengo i seguenti risultati

>>> test_decorated(1)
calculating the value
1
>>> test_decorated(2)
calculating the value
2
>>> test_decorated(1)
cached value is found
1
>>>

Puoi vedere che il secondo test_decorated(1) non eseguirà alcun calcolo, perché abbiamo già memorizzato nella cache il risultato.

Ora voglio capire ulteriormente, quindi definisco

def test_cached(n):
    cache = {}
    print "printing cache"
    print cache
    print "cache printed"    
    if n in cache:
        print "cached value is found"
        return cache[n]
    else:
        print "calculating the value"
        val = n
        cache[n] = val
        return val

Ho pensato che otterrò gli stessi risultati di cui sopra quando chiamo test_cached . Tuttavia, la risposta è NO e la funzione test_cached non ha memorizzato alcun valore calcolato. Ecco il risultato:

>>> test_cached(1)
printing cache
{}
cache printed
calculating the value
1
>>> test_cached(2)
printing cache
{}
cache printed
calculating the value
2
>>> test_cached(1)
printing cache
{}
cache printed
calculating the value
1
>>> 

Come puoi vedere, il secondo test_cached(1) ricalcola nuovamente il risultato.

Vorrei sapere perché questi due approcci danno risultati diversi, ad es. perché il primo approccio memorizza correttamente i risultati nella cache, ma il secondo fallisce

    
posta user565739 06.11.2015 - 09:48
fonte

1 risposta

2

cache è inizializzato quando fai cache = {} che accade ogni volta che chiami test_cached . Quindi, il caso è sempre vuoto (e inutile) quando vuoi usarlo.

Nel tuo codice originale, cache viene inizializzato anche quando fai cache = {} ma lo fai solo quando chiami memorize che viene eseguito una sola volta: quando lo fai: test_decorated = memorize(test) .

Quando chiami test_decorated , ricorda in genere quale oggetto cache deve essere utilizzato (e modificato se necessario).

(Se vuoi saperne di più su questo, potrebbe essere interessante cercare le chiusure in Python).

    
risposta data 06.11.2015 - 11:45
fonte

Leggi altre domande sui tag