python如何阻止类被子类化?

ale*_*xis 11 python final subclass

我在python文档中遇到了以下内容:

布尔([X])

使用标准真值测试程序将值转换为布尔值.如果x为false或省略,则返回False; 否则返回True.bool也是一个类,它是int的子类.类bool不能进一步子类化.它唯一的例子是假和真.

我从来没有想过要进行子类化bool,但很自然地我立即尝试了它,果然:

>>> class Bool(bool):
    pass

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    class Bool(bool):
TypeError: Error when calling the metaclass bases
    type 'bool' is not an acceptable base type
Run Code Online (Sandbox Code Playgroud)

所以,问题是:这是怎么做到的?我可以应用相同的技术(或不同的技术)来标记我自己的类final,即保持它们不被子类化吗?

Mar*_*ers 15

bool类型在C中定义,其tp_flags插槽故意不包括该Py_TPFLAGS_BASETYPE标志.

C型需要自己标注明确的子类化.

要为自定义Python类执行此操作,请使用元类:

class Final(type):
    def __new__(cls, name, bases, classdict):
        for b in bases:
            if isinstance(b, Final):
                raise TypeError("type '{0}' is not an acceptable base type".format(b.__name__))
        return type.__new__(cls, name, bases, dict(classdict))

class Foo:
    __metaclass__ = Final

class Bar(Foo):
    pass
Run Code Online (Sandbox Code Playgroud)

得到:

>>> class Bar(Foo):
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __new__
TypeError: type 'Foo' is not an acceptable base type
Run Code Online (Sandbox Code Playgroud)