Source code for usf.memoize
# -*- coding: utf-8 -*-
################################################################################
# copyright 2008 Gabriel Pettier <gabriel.pettier@gmail.com> #
# #
# This file is part of UltimateSmashFriends #
# #
# UltimateSmashFriends is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# UltimateSmashFriends is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with UltimateSmashFriends. If not, see <http://www.gnu.org/licenses/>.#
################################################################################
'''
This module provide simple implementation of the memoize pattern, implemented
as a decorator.
usage::
@memoize
def my_determinist_pure_function(*args, **kwargs):
do stuff
my_determinist_pure_function(some_params) # first call with those params, slow
...
my_determinist_pure_function(some_params) # return result imediatly
...
my_determinist_pure_function(other_params) # slow again, because new params
...
my_determinist_pure_function(other_params) # return result immediatly
of course, if params/results are memory huger, or the function is called with
lot of different params, that will eat some memory, but if you often need the
same result, that can bring you a lot of speed.
'''
# the wraps decorator allow us to define well behaved decorator, that keep the
# name, doc and other important things of decorated functions
from functools import wraps
[docs]def memoize(function):
"""
Any function decorated with memoize will cache it's results and send them
directly when called with same parameters as before, without calling the
actual code, please only use with functions which result depend only of
parameters (not time, state of the game or such).
"""
cache = {}
@wraps(function)
def decorated_function(*args, **kwargs):
""" this docstring will be replaced by function's one when decorator is
used
"""
params = (args) + tuple(zip(kwargs.keys(), kwargs.values()))
try:
return cache[params]
except KeyError:
val = function(*args, **kwargs)
try:
cache[params] = val
except TypeError, e:
print e, params
return val
return decorated_function