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