Esiste un modo canonico per memorizzare nella cache i metodi di istanza in python?

5

Ho alcune funzioni computazionalmente intensive nel mio script python che vorrei memorizzare nella cache. Sono andato alla ricerca di soluzioni sullo stack overflow e ho trovato molti link:

  1. link
  2. link
  3. link
  4. link (Ho usato questo per le applicazioni dei flask, ma questa non è un'applicazione per i flask).

Alla fine, ho finito per incollarlo nel mio programma. Sembra abbastanza semplice - e funziona bene.

class memoized(object):
    '''Decorator. Caches a function's return value each time it is called.
    If called later with the same arguments, the cached value is returned
    (not reevaluated).
    '''
    def __init__(self, func):
        self.func = func
        self.cache = {}

    def __call__(self, *args):
        if not isinstance(args, collections.Hashable):
            return self.func(*args)
        if args in self.cache:
            return self.cache[args]
        else:
            value = self.func(*args)
            self.cache[args] = value
            return value

    def __repr__(self):
        '''Return the function's docstring.'''
        return self.func.__doc__

    def __get__(self, obj, objtype):
        '''Support instance methods.'''
        return functools.partial(self.__call__, obj)

Tuttavia, mi chiedo se esiste una best practice canonica in Python. Suppongo di aver pensato che ci sarebbe stato un pacchetto molto usato per gestire questo e sono confuso sul motivo per cui questo non esiste. Il link è solo sulla versione .6 e la sintassi è più complessa della semplice aggiunta di un decoratore @memoize, come in altre soluzioni.

    
posta bernie2436 28.10.2014 - 17:23
fonte

1 risposta

8

Non esiste un modo canonico, univoco e pitodico per farlo. Nulla di cui sono a conoscenza, in ogni caso - e sto parlando come qualcuno che ha guardato, e chi è l'autore di a pacchetto memoizing di successo .

Tuttavia, credo che la tua mancanza di arte nota trovata possa essere un problema terminologico tanto quanto qualsiasi altra cosa. Hai richiesto la memorizzazione nella cache . Questo è un termine appropriato, ma è eccessivamente ampio. La memorizzazione nella cache dei risultati di una particolare chiamata o attività di funzione per un uso successivo è più specificamente indicata come memoizing o memoization . E infatti ci sono molti pacchetti di memoizing disponibili dalla community , così come molte ricette ( per esempio, questa ). Ho anche visto le funzioni di memoizng in molti pacchetti di utilità multiuso. Molti di loro sono maturi, temprati dalla battaglia e costantemente utilizzati nella produzione - non semplice "codice versione 0.6".

Perché la memoizzazione non è più gestita canonicamente o idiomaticamente non posso dire. Forse perché ci sono vari modi per realizzarlo con differenti virtù e compromessi. O forse perché ci sono già tanti approcci diversi in uso. Trovo spesso che le funzioni - "appiattire un elenco di liste" è un'altra - che altre comunità linguistiche convergono con entusiasmo ma che la comunità o i poteri di Python sembrano preferire la gestione come ricette piuttosto che il commit su una specifica API. In ogni caso, se il tuo codice funziona, benvenuto nelle file dei memoizers di successo!

Aggiornamento

Poiché la libreria standard Python 3 (per la versione 3.2 e successive) include un% decoratore di% co_de ( documentazione qui ), dovrei dire che sembra un tentativo tardivo di standardizzare il caso d'uso della memoria più comune. Che sia arrivato così tardi nell'evoluzione di Python è probabilmente il motivo per cui non esiste una soluzione comune, ma per il nuovo codice, è più vicino a quello canonico che stai per trovare.

    
risposta data 28.10.2014 - 17:44
fonte

Leggi altre domande sui tag