13

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

布尔([x])

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

我这辈子从没想过 subclass 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

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

4

1 回答 1

19

bool类型是在 C 中定义的,并且它的tp_flags插槽故意不包含Py_TPFLAGS_BASETYPEflag

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

给出:

>>> 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
于 2013-04-17T09:42:06.847 回答