I subclassed dict
in order to have a volatile version: one where its values dissapear when some time passes after the last update(1):
import time
import collections
class Dict10min(dict):
def __init__(self):
super().__init__(self)
self.expire = 0 # when to expire
def __getitem__(self, item):
if time.time() < self.expire:
val = dict.__getitem__(self, item)
return val
else:
# purging the dict
self.clear()
raise KeyError("key {item} does not exist anymore".format(item=item))
def get(self, item, d=None):
if time.time() < self.expire:
try:
val = dict.__getitem__(self, item)
except KeyError:
return d
else:
return val
else:
# purging the dict
self.clear()
return None
def __setitem__(self, key, value):
# set expire time at 10 minutes from now
self.expire = time.time() + 5 # 5 seconds for tests, will be 600
dict.__setitem__(self, key, value)
# solution for update is from @johnrsharpe at http://stackoverflow.com/a/30242574/903011
def update(self, other=None, **kwargs):
if other is not None:
for k, v in other.items() if isinstance(other, collections.Mapping) else other:
self[k] = v
for k, v in kwargs.items():
self[k] = v
a = Dict10min()
a[1] = 2
time.sleep(6)
print(a.get(1))
a[3] = 4
print(a.get(1))
b = Dict10min()
b[1] = 2
time.sleep(6)
try:
print(b[1])
except KeyError:
print("entry does not exist anymore")
b[3] = 4
try:
print(b[1])
except KeyError:
print("entry does not exist anymore")
This correctly outputs
None
None
entry does not exist anymore
entry does not exist anymore
The part which is missing is the one which handles the overall Dict10min
object: when accessing it as a whole none of __getitem__
nor .get()
is used and what is returned is the actual content of the dict (and not the time-altered version).
Where should I hook in order to capture the moment where my object is accessed as a whole (to return {}
)?
(1)the code was updated following @TomDalton comment