I would like to subclass list
and trigger an event (data checking) every time any change happens to the data. Here is an example subclass:
class MyList(list):
def __init__(self, sequence):
super().__init__(sequence)
self._test()
def __setitem__(self, key, value):
super().__setitem__(key, value)
self._test()
def append(self, value):
super().append(value)
self._test()
def _test(self):
""" Some kind of check on the data. """
if not self == sorted(self):
raise ValueError("List not sorted.")
Here, I am overriding methods __init__
, __setitem__
and __append__
to perform the check if data changes. I think this approach is undesirable, so my question is: Is there a possibilty of triggering data checking automatically if any kind of mutation happens to the underlying data structure?
As you say, this is not the best way to go about it. To correctly implement this, you'd need to know about every method that can change the list.
The way to go is to implement your own list (or rather a mutable sequence). The best way to do this is to use the abstract base classes from Python which you find in the collections.abc
module. You have to implement only a minimum amount of methods and the module automatically implements the rest for you.
For your specific example, this would be something like this:
from collections.abc import MutableSequence
class MyList(MutableSequence):
def __init__(self, iterable=()):
self._list = list(iterable)
def __getitem__(self, key):
return self._list.__getitem__(key)
def __setitem__(self, key, item):
self._list.__setitem__(key, item)
# trigger change handler
def __delitem__(self, key):
self._list.__delitem__(key)
# trigger change handler
def __len__(self):
return self._list.__len__()
def insert(self, index, item):
self._list.insert(index, item)
# trigger change handler
Some methods are slow in their default implementation. For example __contains__
is defined in the Sequence
class as follows:
def __contains__(self, value):
for v in self:
if v is value or v == value:
return True
return False
Depending on your class, you might be able to implement this faster. However, performance is often less important than writing code which is easy to understand. It can also make writing a class harder, because you're then responsible for implementing the methods correctly.
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