Skip to content

Instantly share code, notes, and snippets.

@msukmanowsky
Created March 12, 2014 14:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msukmanowsky/9508313 to your computer and use it in GitHub Desktop.
Save msukmanowsky/9508313 to your computer and use it in GitHub Desktop.
Handy little decorator to cache a list of dictionaries returned from some long running operation like web queries.
from functools import wraps
import csv
import os.path
def save_dict_list(filename, **kwargs):
"""Decorator to take the results of a function call (assumed to be a
``list`` of ``dicts``) and cache them in a local file via
csv.DictWriter and serialize them with csv.DictReader"""
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
# check to see if we already have a cached version, if so, return
# that
if os.path.isfile(filename):
with open(filename, 'r') as fp:
reader = csv.DictReader(fp, **kwargs)
return list(reader)
# fetch the list of dictionaries
res = f(*args, **kwargs)
if len(res) == 0: return res # don't bother saving for just one
# save results to file
with open(filename, 'w') as fp:
# instead of specifying fieldnames, just assume alpha order
fieldnames = sorted(res[0].keys())
writer = csv.DictWriter(fp, fieldnames, **kwargs)
writer.writerow({k: k for k in fieldnames}) # header
for row in res:
writer.writerow(row)
return res
return wrapper
return decorator
@save_dict_list('mylist.csv')
def foo():
# first time this runs, it'll call foo for the results, second
# time it'll return results in mylist.csv
print 'Foo called!'
return [
{'first_name': 'Albert', 'last_name': 'Einstein'},
{'first_name': 'Neils', 'last_name': 'Bohr'},
]
@save_dict_list('addresses.csv')
def bar():
# do some long running / expensive query to a webservice
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment