5

Ho scritto una piccola lezione per memorizzare persistentemente alcune funzioni costose che eseguono varie analisi statistiche di reti casuali.Python: strategie per la memoizzazione persistente delle funzioni con argomenti di funzione?

Queste sono tutte funzioni pure; tutti i dati sono immutabili. Tuttavia, alcune funzioni assumono funzioni come argomenti.

Rendere le chiavi basate su questi argomenti è un piccolo problema, poiché in Python l'uguaglianza dell'oggetto della funzione è equivalente all'identità dell'oggetto della funzione, che non persiste tra le sessioni, anche se l'implementazione della funzione non cambia.

Attualmente sto violando questo problema utilizzando il nome della funzione come stringa, ma questo solleva il suo sciame di problemi quando si inizia a pensare di modificare l'implementazione della funzione o di funzioni anonime e così via. Ma probabilmente non sono il primo a preoccuparmi di cose del genere.

Qualcuno ha delle strategie per la memoizzazione persistente delle funzioni con argomenti di funzione in Python?

+0

possibile duplicato di [Memorizzazione persistente in Python] (http://stackoverflow.com/questions/9320463/persistent-memoization-in-python) –

+2

@DanatheSane che non è un duplicato --- non discute la memoizzazione persistente tra invocazioni in cui le funzioni sono argomenti della funzione memorizzata. – tobyodavies

risposta

2

Date un'occhiata a utilizzare questo come l'identità della funzione

[getattr(func.__code__,s) 
for s in ['co_argcount', 'co_cellvars', 'co_code', 'co_consts', 
      'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 
      'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 
      'co_varnames'] 
] 

che dovrebbe gestire correttamente modificando l'implementazione in qualsiasi modo ...

+0

Grazie. Penso che qualcosa del genere che ricorre sulle funzioni memorizzate in "co_names" dovrebbe farlo. Sono stato felicemente sorpreso che il "co_code" fosse lo stesso su diverse piattaforme diverse e versioni di Python nei miei test iniziali. Credo di aver bisogno di leggere sulla macchina virtuale Python. –

+0

Qualcosa di simile funziona per oggetti chiamabili generici? Pur evitando le impurità come i nomi globali va bene, proibire l'uso di un qualsiasi callable diverso da una funzione sarebbe indesiderabile se potesse essere aiutato. – max

+0

@max no, non lo farà. Sarebbe impossibile farlo in generale in quanto ciò che costituisce un cambiamento nell'attuazione di un callable generale è definito dalla classe di questo callable. Il più vicino che si possa sperare è che la classe sia picklable o marshalable in modo tale che le rappresentazioni non siano identiche tra le modifiche di implementazione. In alternativa potresti avere il tuo protocollo per determinare la versione dell'implementazione di un callable. – tobyodavies

3

Una possibilità sarebbe quella di utilizzare marshal.dumps(function.func_code)

Produrrà una rappresentazione di stringa per il codice della funzione. Questo dovrebbe gestire modifiche alle implementazioni e funzioni anonime.