Skip to content

Instantly share code, notes, and snippets.

@andres-erbsen
Created October 23, 2011 19:28
Show Gist options
  • Save andres-erbsen/1307759 to your computer and use it in GitHub Desktop.
Save andres-erbsen/1307759 to your computer and use it in GitHub Desktop.
Caching decorator for python, like functools.lru_cache in Python 3.2+ without LRU. Written for easy debugging of dynamic programming algorthms. Also includes that caches to a pickle file, but this is only useful for very timeconsuming calls like web reque
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from functools import wraps
try:
import cPickle as pickle
except:
import pickle
def cached(fn):
cache = {}
@wraps(fn)
def usingcache(*args,**kwargs):
try:
key = hash((args,kwargs))
except TypeError:
key = repr((args,kwargs))
try:
return cache[key]
except KeyError:
cache[key] = fn(*args,**kwargs)
return cache[key]
return usingcache
def diskcached(cachefile,saveafter=1):
def cacheondisk(fn):
try:
with open(cachefile,'rb') as f:
cache = pickle.load(f)
except:
cache = {}
unsaved = [0]
@wraps(fn)
def usingcache(*args,**kwargs):
try:
key = hash((args,kwargs))
except TypeError:
key = repr((args,kwargs))
try:
ret = cache[key]
except KeyError:
ret = cache[key] = fn(*args,**kwargs)
unsaved[0] += 1
if unsaved >= saveafter:
with open(cachefile,'wb') as f:
pickle.dump(cache,f)
unsaved[0] = 0
return ret
return usingcache
return cacheondisk
def main():
#@diskcached('fibo',3)
@cached
def fib(n):
if n in [1,2]:
return 1
return fib(n-1)+fib(n-2)
print '250th fibonacci number:',fib(250)
return 0
if __name__ == '__main__':
main()
@bjodah
Copy link

bjodah commented May 21, 2012

I suggest adding functools.wraps to the wrapper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment