Superclass for cache value objects by its constructor arguments (see the Date class for example).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | class Cacheable(object):
"""Generic cacheable value object superclass."""
def __new__(cls, *args, **kwargs):
attr = "_%s__cache" % cls.__name__
cache = getattr(cls, attr, None)
if cache is None:
cache = {}
setattr(cls, attr, cache)
key = (args, tuple(kwargs.iteritems()))
obj = cache.get(key, None)
if obj is None:
obj = super(Cacheable, cls).__new__(cls, *args, **kwargs)
cache[key] = obj
return obj
class Date(Cacheable):
"""Example cacheable date class.
>>> d = Date(2004, 1, 1)
>>> d.day, d.month, d.year
(1, 1, 2004)
>>> str(d)
'2004-01-01'
>>> d is Date(2004, 1, 1)
True
"""
__slots__ = ("__year", "__month", "__day")
def __init__(self, year, month, day):
self.__day = day
self.__month = month
self.__year = year
day = property(lambda self: self.__day)
month = property(lambda self: self.__month)
year = property(lambda self: self.__year)
def __str__(self):
return "%04d-%02d-%02d" % (self.__year, self.__month, self.__day)
|
Tags: oop
Very nice! This can also be easily repurposed to use memcached as the backend cache to make Cacheable objects automagically cached in a distributed network cache.
References: