【问题标题】:Python 3 : Two classes with comon __init_subclass__()Python 3:两个具有共同 __init_subclass__() 的类
【发布时间】:2019-05-03 18:56:52
【问题描述】:

我有两个类有一个共同的__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'
                )

当然,AB 有更多的方法,我只是为了一个最小的例子而省略了。我怎样才能避免代码重复?我不能让AB 从一个公共基类继承并在那里定义__init_subclass__,因为这会强制AB 拥有required_class_variables,而我想拥有@ 的子类987654331@ 和 B 拥有它们。 (即使该基类是抽象基类也是如此。)

有没有办法通过__init_subclass__ 实现这一目标?还是我最终需要使用元类或类装饰器?

【问题讨论】:

    标签: python-3.x oop metaprogramming


    【解决方案1】:

    您可以在 Base 类中添加一个静态方法,并分别在 AB__init_subclass__() 上调用此方法,如下所示:

    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)
    

    【讨论】:

      猜你喜欢
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-28
      • 2018-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-26
      相关资源
      最近更新 更多