Python 3: два класса с запятой __init_subclass __ () - PullRequest
0 голосов
/ 03 мая 2019

У меня есть два класса с общим методом __init_subclass__().__init_subclass__() проверяет, установлены ли в наследующем классе некоторые переменные класса (но в конце это может быть еще более сложный код; я просто хотел привести пример):

class A():
    def __init_subclass__(cls):
        # Validate required class variables
        required_class_variables = [
            "a",
            "b",
        ]
        for required_class_variable in required_class_variables:
            if not hasattr(cls, required_class_variable):
                raise TypeError(
                    f'Class {cls} lacks `{required_class_variable}` \
                    class attribute'
                )

class B():
    def __init_subclass__(cls):
        # Validate required class variables
        required_class_variables = [
            "a",
            "b",
        ]
        for required_class_variable in required_class_variables:
            if not hasattr(cls, required_class_variable):
                raise TypeError(
                    f'Class {cls} lacks `{required_class_variable}` \
                    class attribute'
                )

Конечно, A и B имеют больше методов, которые я просто опускаю ради минимального примера.Как я могу избежать повторения кода здесь?Я не могу заставить A и B наследоваться от общего базового класса и определить там __init_subclass__, потому что это заставит A и B иметь обязательные переменные_класса, тогда как я хочу иметь дочерние классы A и B чтобы иметь их.(Это верно, даже если этот базовый класс является абстрактным базовым классом.)

Есть ли способ достичь этого с помощью __init_subclass__?Или мне, наконец, нужно работать с метаклассом или декоратором класса?

1 Ответ

0 голосов
/ 03 мая 2019

Вы можете добавить статический метод в базовый класс и вызвать этот метод для __init_subclass__() из A и B соответственно, например, так:

class Base:
    @staticmethod
    def init_subclass(cls):
        required_class_variables = ["a", "b"]
        for required_class_variable in required_class_variables:
            if not hasattr(cls, required_class_variable):
                raise ValueError(
                    f"{cls} lacks required class variable"
                    f"{required_class_variable}!"
                )


class A(Base):
   def __init_subclass__(cls):
       Base.init_subclass(cls)


class B(Base):
   def __init_subclass__(cls):
       Base.init_subclass(cls)
...