|
Description:
Good demonstration of inheriting python default object types. Define a maximum size (items, not bytes) to limit to and use as a normal dictionary (be careful to have KeyError exception handling, or use the dictionary's get method with a default value).
Source: Text Source
import time
class SizedDict(dict):
''' Sized dictionary without timeout. '''
def __init__(self, size=1000):
dict.__init__(self)
self._maxsize = size
self._stack = []
def __setitem__(self, name, value):
if len(self._stack) >= self._maxsize:
self.__delitem__(self._stack[0])
del self._stack[0]
self._stack.append(name)
return dict.__setitem__(self, name, value)
def get(self, name, default=None, do_set=False):
try:
return self.__getitem__(name)
except KeyError:
if default is not None:
if do_set:
self.__setitem__(name, default)
return default
else:
raise
class CacheDict(dict):
''' A sized dictionary with a timeout (seconds) '''
def __init__(self, size=1000, timeout=None):
dict.__init__(self)
self._maxsize = size
self._stack = []
self._timeout = timeout
def __setitem__(self, name, value, timeout=None):
if len(self._stack) >= self._maxsize:
self.__delitem__(self._stack[0])
del self._stack[0]
if timeout is None:
timeout = self._timeout
if timeout is not None:
timeout = time.time() + timeout
self._stack.append(name)
dict.__setitem__(self, name, (value, timeout))
def get(self, name, default=None):
try:
focus = self.__getitem__(name)
if focus[1] is not None:
if focus[1] < time.time():
self.__delitem__(name)
self._stack.remove(name)
raise KeyError
return focus[0]
except KeyError:
return default
Discussion:
This can be used for caching of data where the amount of data cached really matters. Hosting servers, for instance, can impose ram usage limitations, and where you'd really like to store all the information in memory, sometimes you just can't, but you can certainly compromise. Just replace with a regular dict object when you have the memory to burn.
EDIT: Added the CacheDict class. I decided I needed a quick in-memory cache for when I didn't have mcached interfaces available, and added this to a project I'm working on. Figured it compliments the SizedDict class well.
|