I would like create my own collection that has all the attributes of python list and also knows how to save/load itself into/from a database. Also I want to make the load implicit and lazy, as in it doesn't happen at the point of creation of the list, but waits until its first used.
Is there a single__xxx__
method I can override to load the list on first usage of any list property (such aslen
,getitem
,iter
...etc) without having to override them all?
A lazy list is an iterator that behaves like a list and possesses a cache mechanism. A lazy list is potentially infinite and speed performances of the cache is comparable with Python lists. One major difference with original Python list is that lazy list are immutable.
The second big difference between list comprehension and generator expressions is that the latter has lazy evaluation. In this example you can see that once we assign to list comprehension to a variable the sqr function is called on each element.
The range method in Python follows the concept of Lazy Evaluation. It saves the execution time for larger ranges and we never require all the values at a time, so it saves memory consumption as well.
Not a single, but 5 is enough:
from collections import MutableSequence
class Monitored(MutableSequence):
def __init__(self):
super(Monitored, self).__init__()
self._list = []
def __len__(self):
r = len(self._list)
print "len: {0:d}".format(r)
return r
def __getitem__(self, index):
r = self._list[index]
print "getitem: {0!s}".format(index)
return r
def __setitem__(self, index, value):
print "setitem {0!s}: {1:s}".format(index, repr(value))
self._list[index] = value
def __delitem__(self, index):
print "delitem: {0!s}".format(index)
del self._list[index]
def insert(self, index, value):
print "insert at {0:d}: {1:s}".format(index, repr(value))
self._list.insert(index, value)
The correct way of checking if something implements the whole list interface is to check if it is a subclass of MutableSequence
. The ABCs found in the collections
module, of which MutableSequence
is one, are there for two reasons:
to allow you to make your own classes emulating internal container types so that they are usable everywhere a normal built-in is.
to use as argument for isinstance
and issubclass
to verify that an object implements the necessary functionality:
>>> isinstance([], MutableSequence)
True
>>> issubclass(list, MutableSequence)
True
Our Monitored
class works like this:
>>> m = Monitored() >>> m.append(3) len: 0 insert at 0: 3 >>> m.extend((1, 4)) len: 1 insert at 1: 1 len: 2 insert at 2: 4 >>> m.l [3, 1, 4] >>> m.remove(4) getitem: 0 getitem: 1 getitem: 2 delitem: 2 >>> m.pop(0) # after this, m.l == [1] getitem: 0 delitem: 0 3 >>> m.insert(0, 4) insert at 0: 4 >>> m.reverse() # After reversing, m.l == [1, 4] len: 2 getitem: 1 getitem: 0 setitem 0: 1 setitem 1: 4 >>> m.index(4) getitem: 0 getitem: 1 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With