Python memoize decorator

Uma comparação entre node.js e python , mede o tempo de execução de funções fibonacci recursivas, o primeiro é muito mais rápido do que o último, o que pode ser a causa do motor v8.

def memoize(f):
cache
= {}
def decorated_function(*args):
if args in cache:
return cache[args]
else:
cache
[args] = f(*args)
return cache[args]
return decorated_function

Mas você pode usar memoize em python para acelerar, sua forma de função configura um encerramento em cache os valores foram calculados.

Por outro lado, também pode ser implementado por classe :

import collections
import functools

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):

# uncacheable. a list, for instance.

# better to not cache than blow up.

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)

@memoized
def fibonacci(n):
"Return the nth fibonacci number."
if n in (0, 1):
return n
return fibonacci(n-1) + fibonacci(n-2)

print fibonacci(12)

A classe tem uma variável de instância de dict para armazenar os valores, a chave de cache deve ser hash para usar como uma chave de dict, memoized_function([1, 2], [3, 4])não será armazenada em cache.

class Fibonacci(object):

@memoized
def get_result(self, n):
if n in (0, 1):
return n
return self.get_result(n-1) + self.get_result(n-2)
# provided: memoized_get_result = memoized(get_result)

f
= Fibonacci()
f
.get_result(10)

A definição de __get__deixa f.get_result(*args)ser igual a f.memoized_get_result.__call__(f.memoized_get_result, *args)e torna possível decorar métodos de instância.