Какие классы нельзя подклассифицировать?

Есть ли какое-либо правило о том, какие встроенные и стандартные классы библиотек не являются подклассами ( "final" )?

Как и в Python 3.3, вот несколько примеров:

  • bool
  • function
  • operator.itemgetter
  • slice

Я нашел question, который посвящен реализации "окончательных" классов, как в C, так и в чистом Python.

Я хотел бы понять, какие причины могут объяснить, почему класс выбран как "окончательный" в первую очередь.

Ответ 1

Кажется, есть две причины, чтобы класс был "окончательным" в Python.

1. Нарушение инвариантности класса

Классы, которые следуют шаблону Singleton, имеют инвариант, что существует ограниченное (предварительно определенное) количество экземпляров. Любое нарушение этого инварианта в подклассе будет несовместимо с умыслом класса и не будет работать корректно. Примеры:

В этой категории могут быть случаи, отличные от шаблона Singleton, но я не знаю о них.

2. Нет убедительного случая использования

Класс, реализованный на C, требует дополнительной работы, чтобы разрешить подкласс (по крайней мере, в CPython). Выполнение такой работы без убедительного варианта использования не очень привлекательно, поэтому добровольцы с меньшей вероятностью выходят вперед. Примеры:

Примечание 1:

Первоначально я думал, что существуют допустимые варианты использования, но просто недостаточный интерес, в подклассе function и operator.itemgetter. Благодаря @agf, указав, что варианты использования здесь и здесь не убедительны (см. комментарии @agf к вопросу).

Примечание 2:

Меня беспокоит то, что другая реализация Python может случайно разрешить подкласс класса, окончательного в CPython. Это может привести к не переносимому коду (прецедент может быть слабым, но кто-то еще может писать код, который подклассы function, если их Python поддерживает его). Это можно решить, отметив в документации Python все встроенные и стандартные классы библиотек, которые нельзя подклассифицировать, и требуя, чтобы все реализации соответствовали поведению CPython в этом отношении.

Примечание 3:

Сообщение, созданное CPython во всех вышеперечисленных случаях:

TypeError: type 'bool' is not an acceptable base type

Это довольно загадочно, как показывают многочисленные вопросы по этой теме. Я отправлю предложение добавить абзац в документацию, объясняющую окончательные классы, и, возможно, даже изменить сообщение об ошибке:

TypeError: type 'bool' is final (non-extensible)