0

recently i needed to implement some data structures that could tell if they have been modified since a given point in time. Currently i have a ChangeDetectable class that implements the check but the implementation of setting the flag is left for the child classes. Here's a minimal example:

ChangeDetectable class:

class ChangeDetectable:
    def __init__(self):
        self._changed = False

    def save_state(self):
        self._changed = False

    def has_changed(self) -> bool:
        return self._changed

List-like class:

class MyList(MutableSequence, ChangeDetectable):
    def __init__(self):
        super().__init__()
        self._list = list()

    def __getitem__(self, item):
        return self._list.__getitem__(item)

    def __setitem__(self, key, value):
        self._list.__setitem__(key, value)
        self._changed = True

    def __delitem__(self, key):
        self._list.__delitem__(key)
        self._changed = True

    def __len__(self):
        return self._list.__len__()

    def insert(self, index, item):
        self._list.insert(index, item)
        self._changed = True

Dict-like class:

class MyDict(MutableMapping, ChangeDetectable):
    def __init__(self):
        super().__init__()
        self._dict = dict()

    def __getitem__(self, key):
        return self._dict.__getitem__(key)

    def __setitem__(self, key, value):
        self._dict.__setitem__(key, value)
        self._changed = True

    def __delitem__(self, key):
        self._dict.__delitem__(key)
        self._changed = True

    def __iter__(self):
        return self._dict.__iter__()

    def __len__(self):
        return self._dict.__len__()

So my question is: right now children have to implement the right write operation. For instance MyList needs insert method and MyDict does not. Is there a way to implement all the methods i could possibly need in the parent and then only inherit in the children the ones i need? This could make the code cleaner because it would have super() but i wouldn't want to have insert in MyDict.

Thank you.

  • I disagree with "MyList needs insert method and MyDict does not" You need a way to insert into any list and to any dictionary. If you want to override MyList so that it cannot perform an insert, then write an insert method with a `pass`. – rajah9 Sep 21 '20 at 11:28
  • I guess that's right... – Giorgio Ciotti Sep 21 '20 at 17:13

1 Answers1

0

Let me give you a general answer.

Abstract Base Classes

The official documentation for this is quite good: https://docs.python.org/3/library/abc.html.

Also please take a look at this SO question: What are metaclasses in Python?

You create a class like MyABC and then you define all the methods must be implemented and mark them as @abstractmethod. For example, if MyList and MyDict must implement values, then you should define a method values in MyABC. MyList and MyDict inherit from MyABC and must implement values, as seen in this answer.

If MyDict implements something specific to it, as a dictionary, then it simply defines and implements myKeys.

This is answered quite fully at Why use Abstract Base Classes in Python?.

rajah9
  • 9,513
  • 3
  • 39
  • 50