哪些类不能被子类化?

时间:2012-04-08 09:19:03

标签: python class inheritance python-3.x language-design

是否有关于哪些内置和标准库类不可子类化(“最终”)的规则?

从Python 3.3开始,这里有几个例子:

  • bool
  • function
  • operator.itemgetter
  • slice

我发现了一个question来处理C语言和纯Python中“最终”类的实现。

我想了解是什么原因可以解释为什么一个班级被选为首选的“最终”。

1 个答案:

答案 0 :(得分:26)

一个班级似乎有两个原因,最终"在Python中。

1。违反类不变

遵循Singleton模式的类具有不变量,即具有有限(预定)数量的实例。在子类中任何违反此不变量的行为都将与类#39;意图,并不会正常工作。例子:

  • boolTrueFalse;见Guido's comments
  • NoneTypeNone
  • NotImplementedTypeNotImplemented
  • ellipsisEllipsis

此类别中可能存在除Singleton模式以外的情况,但我不知道任何情况。

2。没有说服力的用例

用C实现的类需要额外的工作来允许子类化(至少在CPython中)。在没有令人信服的用例的情况下进行此类工作并不是很有吸引力,因此志愿者不太可能挺身而出。例子:

注1:

我最初认为在functionoperator.itemgetter的子类化中存在有效的用例,但只是兴趣不足。感谢@agf指出提供的{_ 3}}和here用例并不令人信服(请参阅@agf评论问题)。

注2:

我担心的是,另一个Python实现可能会意外地允许子类化CPython中的最终类。这可能导致不可移植的代码(用例可能很弱,但如果Python支持,有人可能仍会编写子类function的代码)。这可以通过在Python文档中标记所有无法子类化的内置和标准库类来解决,并要求所有实现都遵循这方面的CPython行为。

注3:

CPython在上述所有情况下产生的信息是:

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

这是非常神秘的,因为关于这个主题的许多问题都显示出来。我将提交一个建议,在解释最终类的文档中添加一个段落,甚至可能将错误消息更改为:

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