2015-04-28 10 views
6

Supponiamo che tu abbia il seguente decoratore. Come può essere modificato per aggiungere un'appendice a qualche elenco di riferimenti a tutte le funzioni che decora?Come registrare all'interno di un decoratore tutte le funzioni che decora?

def memoize(obj): 
    cache = obj.cache = {} 

    @functools.wraps(obj) 
    def memoizer(*args, **kwargs): 
     if args not in cache: 
      cache[args] = obj(*args, **kwargs) 
     return cache[args] 
    return memoizer 

@memoize 
def foo(bar): 
    return bar ** 3 
+0

Ti importa dove "qualche elenco" è memorizzato? Vuoi che sia una variabile globale o in qualche modo collegata al decoratore stesso? – BrenBarn

+3

renderlo una classe invece di un metodo ... quindi utilizzare una variabile statica per aggiungere ogni oggetto a '__init__' –

+0

@BrenBarn No non mi interessa davvero dove è memorizzato l'elenco. –

risposta

3

Si può facilmente memorizzare un elenco sull'oggetto decoratore-funzione (memoize.decorated):

_decorated = [] 

def memoize(obj): 
    cache = obj.cache = {} 

    # add to the decorated list 
    _decorated.append(obj) 

    @functools.wraps(obj) 
    def memoizer(*args, **kwargs): 
     if args not in cache: 
      cache[args] = obj(*args, **kwargs) 
     return cache[args] 
    return memoizer 

# make the list accessible from the decorator: 
memoize.decorated = _decorated 

Esso può essere utilizzato come:

@memoize 
def foo(bar): 
    return bar ** 3 

print memoize.decorated 

Come nota a margine, si dovrebbe considerare l'archiviazione di WeakRefs in the list, per evitare perdite di memoria o oggetti che non vengono liberati quando non vengono lasciati altri riferimenti "reali".

+2

Usare '__' all'inizio e alla fine dei nomi è scoraggiato, dal momento che quelli dovrebbero essere solo per interni di Python. Non c'è un vero motivo per usare anche un "__" leader qui. (Direi che non ci sono molti motivi per usare anche un singolo trattino basso, ma è più discutibile.) – BrenBarn

+0

@BrenBarn d'accordo, ho corretto la denominazione – shx2

Problemi correlati