5

He escrito una pequeña clase para memorizar persistentemente algunas funciones costosas que hacen varios análisis estadísticos de redes aleatorias.Python: estrategias para memorizar persistentemente funciones con argumentos de funciones?

Todas estas son funciones puras; todos los datos son inmutables. Sin embargo, algunas de las funciones toman funciones como argumentos.

Hacer claves basadas en estos argumentos es un problema pequeño, ya que en Python la igualdad de objetos de función es equivalente a la identidad del objeto de función, que no persiste entre sesiones, incluso si la implementación de la función no cambia.

Estoy pirateando esto por el momento utilizando el nombre de la función como una cadena, pero esto plantea su propio enjambre de problemas cuando uno comienza a pensar en cambiar la implementación de la función o funciones anónimas, etc. Pero probablemente no sea el primero en preocuparse por esas cosas.

¿Alguien tiene alguna estrategia para memorizar persistentemente funciones con argumentos de funciones en Python?

+0

posible duplicado de [Memorización persistente en Python] (http://stackoverflow.com/questions/9320463/persistent-memoization-in-python) –

+2

@DanatheSane que no es un duplicado --- no discute la memorización persistente entre invocaciones donde las funciones son argumentos para la función memorada. – tobyodavies

Respuesta

2

Tener un vistazo a usar esto como la identidad de la función

[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'] 
] 

que debe manejar correctamente el cambio de la puesta en práctica de cualquier manera ...

+0

Gracias. Creo que algo como esto recursing sobre las funciones memorizadas en 'co_names' debería hacerlo. Me sorprendió gratamente que el 'co_code' fuera el mismo en diferentes plataformas y versiones de python en mis pruebas iniciales. Creo que necesito leer en la máquina virtual de Python. –

+0

¿Funcionaría algo similar para objetos llamables en general? Si bien evitar las impurezas, como los nombres globales, está bien, prohibir el uso de cualquier llamador que no sea una función no sería deseable si puede ser ayudado. – max

+0

@max no, no lo hará. Sería imposible hacer esto en general, ya que lo que constituye un cambio en la implementación de un invocable general está definido por la clase de invocable. Lo más cerca que podría esperar es que la clase sea seleccionable o ordenable de manera que las representaciones no sean idénticas entre los cambios de implementación. Alternativamente, podría tener su propio protocolo para determinar la versión de la implementación de un llamante. – tobyodavies

3

Una opción sería utilizar marshal.dumps(function.func_code)

Producirá una representación de cadena para el código de la función. Eso debería manejar las cambiantes implementaciones y funciones anónimas.

Cuestiones relacionadas