Есть ли способ в Python 3 указать, что класс не поддерживает какую-либо операцию, поддерживаемую родительским классом? * Я знаю, что классы могут устанавливать __hash__
на None
, чтобы указать, что тип не сотрясается, но это, похоже, не работает в целом.Как я могу «разгадать» магические методы Python в подклассе?
Например, предположим, что у меня есть некоторый класс коллекции с методом __len__
, и я хочу создать дочерний класс, представляющий неограниченную коллекцию, которая не имеет определенного размера. Если я установил __len__
в None
в подкласс, я получаю уродливое/запутанное сообщение об ошибке, когда я пытаюсь получить длину коллекции.
>>> class C:
... def __len__(self):
... return 3
...
>>> class D(C):
... __len__ = None
...
>>> len(D())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Я хотел бы получить сообщение об ошибке, как если бы D
не определял __len__
вообще:
>>> class E:
... pass
...
>>> len(E())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'E' has no len()
This question связан, однако мой вопрос относится именно к магической методе/перегрузке операторов. Поскольку магические методы Python просматриваются непосредственно по типу объекта, некоторые возможные подходы, такие как переопределение __getattribute__
или использование дескрипторов, здесь не будут работать.
* Примечание: Я знаю, что это нарушит Liskov substitution principle, но если бы я хотел, чтобы тип безопасности, я бы не использовал Python в первую очередь. ;)
Почему бы не поднять 'NotImplementedError' от ребенка? Также обратите внимание, что динамическое типирование не то же самое, что создание разбитой структуры класса; не могли бы вы дать некоторый контекст относительно того, почему вы думаете, что вам нужно это? – jonrsharpe