Ich hab ein Dictionary geschrieben bei dem die Schlüssel nach einer bestimmten Zeit verfallen...
Eigentlich nichts besonderes.
Aber es gibt eine besonderheit im zusammenhang mit python 2.4.
Die ganze class kann als decorator verwendet werden und so als Cache für eine Funktion dienen.
Code: Alles auswählen
import time
class Cache(dict):
__slots__=["timeout","cache"]
def __init__(self,timeout=0):
self.timeout=timeout
self.cache={}
def __setitem__(self,x,y):
super(Cache,self).__setitem__(x,y)
self.cache[x]=time.time()
def __contains__(self,x):
if x in self.cache:
if self.timeout and time.time()-self.cache[x]>self.timeout:
del self[x],self.cache[x]
return False
return True
return False
def __getitem__(self,x):
if x in self:
return super(Cache,self).__getitem__(x)
raise KeyError(x)
def get(self,x,std=None):
if x in self:
return self[x]
return std
def add(self,x,y,t=None):
""""Fügt etwas mit einem anderen Timeout hinzu..."""
t=time.time()-(t or 0)
super(Cache,self).__setitem__(x,y)
self.cache[x]=t
def cleanup(self):
map(self.__contains__,self)
def clear(self):
super(Cache,self).clear()
self.cache.clear()
def __call__(self,func):
def x(a,reset=False,*b,**c):
if a in self and not reset:
return self[a]
y=func(a,*b,**c)
self[a]=y
return y
return x
Code: Alles auswählen
>>> @Cache(10)
... def t(x):
... print "In Cache geladen!"
... return x**2
...
>>> t
<function x at 0x0118E2B0>
>>> t(4)
In Cache geladen!
16
>>> t(4)
16
>>> t(4) #10 sek später
In Cache geladen!
16
>>> @Cache(0) #keys verfallen nie
... def t(x):
... print "In Cache geladen!"
... return x**2
...
>>> t(10)
In Cache geladen!
100
>>> t(10)
100
>>> t(10) #bisschen später
100
>>> t(10) #viel später ;)
100
>>> t(10,reset=True) #reset
In Cache geladen!
100
Ich verwende es selber zum Abfragen größtenteils statischer datenbankdaten damit nicht immer die gleichen daten aus der mysql datenbank abgefragt werden