Skip to content

Commit d9cfa33

Browse files
committed
Added cache in python
1 parent 7dde115 commit d9cfa33

1 file changed

Lines changed: 98 additions & 1 deletion

File tree

docs/index.md

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1386,4 +1386,101 @@ Field class types determines
13861386

13871387
The database column type
13881388
The default HTML widget to avail while rendering a form field
1389-
The minimal validation requirements used in Django admin and in automatically generated forms
1389+
The minimal validation requirements used in Django admin and in automatically generated forms
1390+
1391+
1392+
# Python: An Intro to caching
1393+
1394+
- A cache is a way to store a limited amount of data such that future requests for said data can be retrieved faster. In this article, we’ll look at a simple example that uses a dictionary for our cache. Then we’ll move on to using the Python standard library’s functools module to create a cache.
1395+
- Let’s start by creating a class that will construct our cache dictionary and then we’ll extend it as necessary.
1396+
1397+
```
1398+
class MyCache:
1399+
1400+
def __init__(self):
1401+
"""Constructor"""
1402+
self.cache = {}
1403+
self.max_cache_size = 10
1404+
```
1405+
1406+
There’s nothing in particular that’s special in this class example. We just create a simple class and set up two class variables or properties, cache and max_cache_size. The cache is just an empty dictionary while the other is self-explanatory. Let’s flesh this code out and make it actually do something:
1407+
1408+
```
1409+
import datetime
1410+
import random
1411+
1412+
class MyCache:
1413+
""""""
1414+
1415+
#----------------------------------------------------------------------
1416+
def __init__(self):
1417+
"""Constructor"""
1418+
self.cache = {}
1419+
self.max_cache_size = 10
1420+
1421+
#----------------------------------------------------------------------
1422+
def __contains__(self, key):
1423+
"""
1424+
Returns True or False depending on whether or not the key is in the
1425+
cache
1426+
"""
1427+
return key in self.cache
1428+
1429+
#----------------------------------------------------------------------
1430+
def update(self, key, value):
1431+
"""
1432+
Update the cache dictionary and optionally remove the oldest item
1433+
"""
1434+
if key not in self.cache and len(self.cache) >= self.max_cache_size:
1435+
self.remove_oldest()
1436+
1437+
self.cache[key] = {'date_accessed': datetime.datetime.now(),
1438+
'value': value}
1439+
1440+
#----------------------------------------------------------------------
1441+
def remove_oldest(self):
1442+
"""
1443+
Remove the entry that has the oldest accessed date
1444+
"""
1445+
oldest_entry = None
1446+
for key in self.cache:
1447+
if oldest_entry is None:
1448+
oldest_entry = key
1449+
elif self.cache[key]['date_accessed'] < self.cache[oldest_entry][
1450+
'date_accessed']:
1451+
oldest_entry = key
1452+
self.cache.pop(oldest_entry)
1453+
1454+
#----------------------------------------------------------------------
1455+
@property
1456+
def size(self):
1457+
"""
1458+
Return the size of the cache
1459+
"""
1460+
return len(self.cache)
1461+
```
1462+
1463+
- Here we import the datetime and random modules and then we see the class we created earlier. This time around, we add a few methods. One of the methods is a magic method called __contains__. I’m abusing it a little, but the basic idea is that it will allow us to check the class instance to see if it contains the key we’re looking for. The update method will update our cache dictionary with the new key / value pair. It will also remove the oldest entry if the maximum cache value is reached or exceeded. The remove_oldest method actually does the removing of the oldest entry in the dictionary, which in this case means the item that has the oldest access date. Finally we have a property called size which returns the size of our cache.
1464+
1465+
If you add the following code, we can test that the cache works as expected:
1466+
1467+
```
1468+
if __name__ == '__main__':
1469+
# Test the cache
1470+
keys = ['test', 'red', 'fox', 'fence', 'junk',
1471+
'other', 'alpha', 'bravo', 'cal', 'devo',
1472+
'ele']
1473+
s = 'abcdefghijklmnop'
1474+
cache = MyCache()
1475+
for i, key in enumerate(keys):
1476+
if key in cache:
1477+
continue
1478+
else:
1479+
value = ''.join([random.choice(s) for i in range(20)])
1480+
cache.update(key, value)
1481+
print("#%s iterations, #%s cached entries" % (i+1, cache.size))
1482+
print
1483+
```
1484+
1485+
- In this example, we set up a bunch of predefined keys and loop over them. We add keys to the cache if they don’t already exist. The piece missing is a way to update the date accessed, but I’ll leave that as an exercise for the reader. If you run this code, you’ll notice that when the cache fills up, it starts deleting the old entries appropriately.
1486+
- Now let’s move on and take a look at another way of creating caches using Python’s built-in functools module!

0 commit comments

Comments
 (0)