2012-04-19 16 views
11

Estoy trabajando con xlwt que tiene un límite de 4k sobre cuántos estilos se pueden definir en un documento de Excel.¿Cómo hash * args ** kwargs para la memoria caché de funciones?

Normalmente, se crea estilos de este modo:

style = xlwt.easyxf("font: bold 1") 

Lo cual simplemente se sustituye con

def cached_easyxf(self, format): 
    return self._cache.setdefault(format, xlwt.easyxf(format)) 

que funciona perfectamente. Ahora, descubrí que a veces tengo que pasar argumentos de palabras clave que me hicieron pensar: ¿cómo debo hash la firma args/kwargs?

¿Debo crear una clave de caché basada en str (valor)? ¿Conservar en vinagre? ¿Qué es más robusto?

Para mi situación que parece que sólo puede convertir clave/valor a las cadenas y añadirlo a mis llaves ... pero ahora tengo curiosidad por saber de forma genérica para manejar esto con, por ejemplo tipos unhashable como arg=[1, 2, 3]

def cached_call(*args, **kwargs): 
    return cache.get(what_here) 
cached_call('hello') 
cached_call([1, 2, 3], {'1': True}) 

Respuesta

10

Aquí es la técnica utilizada en functools.lru_cache():

kwd_mark = object()  # sentinel for separating args from kwargs 

def cached_call(*args, **kwargs): 
    key = args + (kwd_mark,) + tuple(sorted(kwargs.items())) 
    return cache.get(key) 

Nota, el código anterior se ocupa de los argumentos de palabras clave, pero no hace ningún intento para manejar los valores no hashable como listas. Su idea para usar el str de una lista es un comienzo razonable. Para configurar objetos, primero deberá ordenar las entradas, str(sorted(someset)). Es posible que otros objetos no tengan un __repr__ o __str__ útil (es decir, que solo muestren el tipo de objeto y la ubicación en la memoria). En resumen, el manejo de argumentos arbitrarios e inigualables requiere una consideración cuidadosa de cada tipo de objeto.

+1

Gracias por la respuesta Raymond! Muy apreciado –

+0

¿Funcionaría lo siguiente igual de bien: 'key = (args, tuple (ordenado (kwds.items())))'? ¿O es más lento debido a las tuplas internas? – max

+0

@max Sí, eso funcionaría. Y sí, los indicadores adicionales reducirían la velocidad un poco y consumirían un poco más de memoria. –

Cuestiones relacionadas