是否有关于哪些内置和标准库类不可子类化(“最终”)的规则?
从 Python 3.3 开始,以下是一些示例:
bool
function
operator.itemgetter
slice
我发现一个问题涉及在 C 和纯 Python 中实现“最终”类。
我想了解什么原因可以解释为什么一个类首先被选为“最终”。
是否有关于哪些内置和标准库类不可子类化(“最终”)的规则?
从 Python 3.3 开始,以下是一些示例:
bool
function
operator.itemgetter
slice
我发现一个问题涉及在 C 和纯 Python 中实现“最终”类。
我想了解什么原因可以解释为什么一个类首先被选为“最终”。
一个类在 Python 中成为“final”似乎有两个原因。
1.违反类不变量
遵循单例模式的类具有一个不变量,即实例数量有限(预先确定)。在子类中任何违反此不变量的行为都将与该类的意图不一致,并且无法正常工作。例子:
bool
: True
, False
; 见圭多的评论NoneType
:None
NotImplementedType
:NotImplemented
ellipsis
:Ellipsis
此类别中可能存在除单例模式以外的情况,但我不知道有任何情况。
2. 没有说服力的用例
在 C 中实现的类需要额外的工作以允许子类化(至少在 CPython 中)。在没有令人信服的用例的情况下做这样的工作并不是很有吸引力,所以志愿者不太可能挺身而出。例子:
function
; 见蒂姆彼得斯的帖子注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)