How does python prevent a class from being subclassed? [duplicate]

时光总嘲笑我的痴心妄想 提交于 2019-11-29 18:00:20

问题


This question already has an answer here:

  • Final classes in Python 3.x- something Guido isn't telling me? 4 answers

I came across the following in the python docs:

bool([x])

Convert a value to a Boolean, using the standard truth testing procedure. If x is false or omitted, this returns False; otherwise it returns True. bool is also a class, which is a subclass of int. Class bool cannot be subclassed further. Its only instances are False and True.

I've never in my life wanted to subclass bool, but naturally I immediately tried it, and sure enough:

>>> 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

So, the question: How is this done? And can I apply the same technique (or a different one) to mark my own classes as final, i.e., to keep them from being subclassed?


回答1:


The bool type is defined in C, and its tp_flags slot deliberately does not include the Py_TPFLAGS_BASETYPE flag.

C types need to mark themselves explicitly as subclassable.

To do this for custom Python classes, use a metaclass:

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

gives:

>>> 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


来源:https://stackoverflow.com/questions/16056574/how-does-python-prevent-a-class-from-being-subclassed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!