2012-04-08 66 views
70

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

对于Python 3.3的,这里有几个例子:

  • bool
  • function
  • operator.itemgetter
  • slice

我发现了一个question与执行交易“最后”的课程,都在C和纯Python。

我想知道什么原因可以解释为什么一个班级首先被选为“最终”。

+4

'NoneType'是另一个示例。 – Duncan 2012-04-08 09:57:43

+4

一个Python实现中的最后一个类可以在另一个实现中被子类化吗?我希望有人能证实它从未发生过。否则,为一个实现编写的代码在移植到另一个实现时可能会中断(也很痛苦:想象一下,如果有人为'function'定义了子类,现在需要重构代码以避免这种继承)。 – max 2012-04-09 20:14:44

+3

请注意,PyPy也拒绝子类化您的四个示例,即使它没有CPython限制。他们可能在其代码库中记录了一个原因。 – 2012-04-09 21:24:42

回答

23

在Python中,类似于“最终”似乎有两个原因。

1.类不变遵循Singleton模式

类违反有一个不变的是有实例的有限(预先确定的)号码。在子类中任何违反此不变量的操作都将与类的意图不一致,并且无法正常工作。示例:

  • boolTrueFalse;看到Guido's comments
  • NoneTypeNone
  • NotImplementedTypeNotImplemented
  • ellipsisEllipsis

有可能比该类别中的Singleton模式其他情况下,但我不知道有任何。

2.无说服力的用例

用C语言实现的类需要额外的工作,让子类(至少在CPython的)。没有令人信服的用例做这样的工作并不是很有吸引力,所以志愿者不太可能挺身而出。示例:

注1:

我原本以为有有效的用例,但利率完全不够,在functionoperator.itemgetter子类。感谢@agf指出,herehere提供的用例不具有说服力(请参阅@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) 
+3

当然,如果你正在编写薛定谔猫的模拟,你可能想要将'bool'继承为'unknown':-P只是在开玩笑 – Endophage 2012-04-11 21:47:25

+8

@Endophage:一个Qbit肯定是一个有用的类型,但它不是一个sublcass实际上,'bool'完全相反,每一个布尔值都是一种qbit!恰好被观察到的一个。不过,我可能会用'__subclasscheck__'和朋友处理这种情况。 – SingleNegationElimination 2012-04-11 21:51:26

+4

@TokenMacGuy出色的观察!那么为什么我们没有Python中的Qbit类,bool是一个子类!我要求它应该是这样! :-P – Endophage 2012-04-12 01:10:01