哪些类不能被子类化? [英] Which classes cannot be subclassed?
问题描述
有没有关于哪些内置和标准库类不能子类化(final)的规则?
从Python 3.3开始, :
-
bool
-
函数
-
operator.itemgetter
-
slice
我发现一个问题,涉及final类的实现,纯Python。
我想了解什么原因可以解释为什么一个类首先被选择为final。
Python中的类似乎是final的两个原因。
1。违反类不变性
后面的类Singleton模式有一个不变量,有一个有限的(预定)数量的实例。任何在子类中违反这个不变式都会与类的意图不一致,并且不能正常工作。示例:
-
bool
:True
,False
;请参阅 Guido的意见 -
无类型
:None
-
NotImplementedType
: -
省略号
:省略号
>
在此类别中可能存在除了Singleton模式以外的其他情况,但我不知道任何。
2。没有说服用例
在C中实现的类需要额外的工作才能允许子类化(至少在CPython中)。没有令人信服的用例做这样的工作不是很有吸引力,所以志愿者不太可能提出。示例:
-
function
;请参阅 Tim Peters的帖子
注意1:
我最初认为有有效的用例,在子类化
function
和 operator.itemgetter
。感谢@agf指出提供的使用案例这里和此处无法令人信服(请参阅@agf评论的问题)。 注意2:
我担心的是,另一个Python实现可能会意外地允许子类化在CPython中最终的类。这可能导致非便携式代码(一个用例可能很弱,但如果他们的Python支持它,有人可能仍然编写子类 function
的代码)。这可以通过在Python文档中标记所有不能被子类化的内置和标准库类来解决,并要求所有实现遵循CPython的行为。
注意3:
在所有上述情况下,CPython产生的消息是:
TypeError:type'bool'不是可接受的基本类型
关于这个问题的许多问题显示。我将提交一个建议,在解释最终类的文档中添加一段,甚至可以将错误消息更改为:
TypeError:type'bool'is final(non-extensible)
Is there any rule about which built-in and standard library classes are not subclassable ("final")?
As of Python 3.3, here are a few examples:
bool
function
operator.itemgetter
slice
I found a question which deals with the implementation of "final" classes, both in C and pure Python.
I would like to understand what reasons may explain why a class is chosen to be "final" in the first place.
There seems to be two reasons for a class to be "final" in Python.
1. Violation of Class Invariant
Classes that follow Singleton pattern have an invariant that there's a limited (pre-determined) number of instances. Any violation of this invariant in a subclass will be inconsistent with the class' intent, and would not work correctly. Examples:
bool
:True
,False
; see Guido's commentsNoneType
:None
NotImplementedType
:NotImplemented
ellipsis
:Ellipsis
There may be cases other than the Singleton pattern in this category but I'm not aware of any.
2. No Persuasive Use Case
A class implemented in C requires additional work to allow subclassing (at least in CPython). Doing such work without a convincing use case is not very attractive, so volunteers are less likely to come forward. Examples:
function
; see Tim Peters' post
Note 1:
I originally thought there were valid use cases, but simply insufficient interest, in subclassing of function
and operator.itemgetter
. Thanks to @agf for pointing out that the use cases offered here and here are not convincing (see @agf comments to the question).
Note 2:
My concern is that another Python implementation might accidentally allow subclassing a class that's final in CPython. This may result in non-portable code (a use case may be weak, but someone might still write code that subclasses function
if their Python supports it). This can be resolved by marking in Python documentation all built-in and standard library classes that cannot be subclassed, and requiring that all implementations follow CPython behavior in that respect.
Note 3:
The message produced by CPython in all the above cases is:
TypeError: type 'bool' is not an acceptable base type
It is quite cryptic, as numerous questions on this subject show. I'll submit a suggestion to add a paragraph to the documentation that explains final classes, and maybe even change the error message to:
TypeError: type 'bool' is final (non-extensible)
这篇关于哪些类不能被子类化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!