Last active
September 2, 2022 18:48
-
-
Save giner/78f8f631e5f41ec2a3063fb9498a462a to your computer and use it in GitHub Desktop.
Python: Simple way to cache function result using decorator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
def cache(func): | |
def wrapper(*args, **kwargs): | |
if hasattr(func, "cache"): | |
return func.cache | |
func.cache = func(*args, **kwargs) | |
return func.cache | |
return wrapper | |
@cache | |
def myfun(myvar, mykey = "myval"): | |
return myvar, mykey | |
print(myfun("val1", mykey = "keyval1")) | |
print(myfun("val2", mykey = "keyval2")) | |
# OUTPUT: | |
# ('val1', 'keyval1') | |
# ('val1', 'keyval1') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import json | |
import hashlib | |
import os | |
def cache(arg): | |
def decorator(func): | |
def wrapper(*args, **kwargs): | |
func_sig = (func.__module__, func.__name__, args, tuple(sorted(kwargs.items()))) | |
if persistent: | |
cache_dir = '/tmp/cache' | |
func_hash = hashlib.sha256(str(func_sig).encode('utf-8')).hexdigest() | |
cache_file = os.path.join(cache_dir, func_hash + '.json') | |
if not os.path.isdir(cache_dir): | |
os.mkdir(cache_dir, mode = 0o700) | |
if not hasattr(func, "cache"): | |
func.cache = {} | |
if not func_sig in func.cache: | |
if persistent: | |
if os.path.isfile(cache_file): | |
with open(cache_file, 'r') as file: | |
func.cache[func_sig] = json.load(file) | |
else: | |
func.cache[func_sig] = func(*args, **kwargs) | |
with open(cache_file, 'w') as file: | |
json.dump(func.cache[func_sig], file) | |
else: | |
func.cache[func_sig] = func(*args, **kwargs) | |
return func.cache[func_sig] | |
return wrapper | |
if callable(arg): | |
persistent = False | |
return decorator(arg) | |
else: | |
persistent = arg | |
return decorator | |
# Examples | |
# In memory cache | |
@cache | |
def myfun(myvar, mykey = "myval"): | |
return myvar, mykey | |
# Persistent cache | |
@cache(True) | |
def myfun2(myvar, mykey = "myval2"): | |
return myvar, mykey |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment