Как python предотвращает подклассы класса? [дубликат]

этот вопрос уже есть ответ здесь:

я наткнулся на следующее в python docs:

bool ([x])

преобразовать значение в логическое, используя стандартная процедура проверки правды. Если x равно false или опущено, это возвращает False; в противном случае вернуть true. bool также является классом, который является подклассом int. класс bool не может быть подклассом дальше. его единственными экземплярами являются False и Истинный.

Я никогда в своей жизни не хотел подкласса 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, то есть, чтобы они не были подклассами?

1 ответов


на bool тип определяется в C, а его tp_flags слот намеренно не включает в себя Py_TPFLAGS_BASETYPE флаг.

типы C должны пометить себя явно как subclassable.

чтобы сделать это для пользовательских классов 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