1

Sometimes I'd like to subclass, but disable or delete some of the methods I don't need, and don't want to have to deal with. If there was only one or two, I'd just include them and overwrite them with a NotImplemented error. But when there's more, I start copy/pasting and have an eery feeling of "there must be a better way".

Here's an example where I'm subclassing deque, and only want append and extend methods.

from collections import deque
from functools import wraps, partialmethod

attributes_to_disable = {'appendleft', 'extendleft', 'insert', 'pop', 'popleft', 'remove', 'reverse', 'rotate', 'clear'}

def _not_implemented(self, method_name, *args, **kwargs):
    raise NotImplementedError("")

class InfiniteSeq(deque):
    @wraps(deque)
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self.max_idx = 0  # should correspond to the number of items added

    def append(self, x) -> None:
        super().append(x)
        self.max_idx += 1

    def extend(self, iterable: Iterable) -> None:
        iterable = list(iterable)
        super().extend(iterable)
        self.max_idx += len(iterable)

    for attr in attributes_to_disable:
        locals()[attr] = partialmethod(_not_implemented, method_name=attr)
        
## removing attributes this way doesn't work:
# for attr in attributes_to_disable:
#    delattr(InfiniteSeq, attr)
thorwhalen
  • 1,920
  • 14
  • 26
  • 4
    If you find yourself having to disable or delete methods, your design is incorrect: you must not inherit. Consider encapsulation over inheritance. Case in point: your example is a canonical example of subclassing when it should have been encapsulation (create a self._deque and simply use it in your methods). – spectras Feb 15 '21 at 23:30
  • That's what [mixins](https://stackoverflow.com/questions/533631/what-is-a-mixin-and-why-are-they-useful) are for. – Selcuk Feb 15 '21 at 23:34
  • @spectras I think you mean composition over inheritance but 100% agree – juanpa.arrivillaga Feb 15 '21 at 23:36
  • @juanpa.arrivillaga yes definitely, it's late here. Please read "composition" instead of "encapsulation" everywhere in my previous message. – spectras Feb 15 '21 at 23:45
  • 1
    "delegation" is the term I've seen used. – thorwhalen Feb 15 '21 at 23:56
  • @spectras (and agreers above): I agree too. For my particular purpose, composition/delegation is what makes sense. That said, I'll leave my question up because it's still a valid how-to question, and don't want to pre-judge with a blanket should-not-do answer. – thorwhalen Feb 16 '21 at 00:43
  • Your question is fine to me. I use comments for quick "nudge in the right direction" when I don't feel like writing a fully fledged answer. – spectras Feb 16 '21 at 00:49

0 Answers0