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)