如何在没有代码重复的情况下覆盖多个 类 (Python)

How to override in multiple classes without code duplication (Python)

我有一个父 class A,很少有 class 继承自它(BC、...)。

我有一些函数 is_class_AA 中实现,我想以相同的方式在 BC 中覆盖它。

假设:

class A:
    def is_class_A():
        print("We are in class A")

class B(A):
    def is_class_A():
        print("Nope")

class C(A):
    def is_class_A():
        print("Nope")

请记住 class A 和其他函数中实现的两个函数都很长,而且更复杂。

我想到了 2 个解决方案,以避免 BC 实施中的重复:

在class中使用 C:

def is_class_A():
    return B.is_class_A()

我不确定这将如何发挥作用,因为 C 的对象不是 B 的对象。而且我没有在这里传递任何东西 self,所以我不知道这将如何工作,也许类似的东西可以?

下一个解决方案是使用另一个遗产:

class C(B)

这并不总是有效,因为并非总是可行(如果它们具有不同的属性)并且可能不符合设计目的。

到目前为止我最好的尝试是使用另一个 class:

class BC(A):
    def is_class_A():
        print("Nope")

class B(BC):
    pass

class C(BC):
    pass

你怎么看?一些更多的想法?也许是一些不涉及程序设计的更技术性的东西?

谢谢。

一种选择是在全局范围内定义一次备用方法,然后直接进行 class 属性分配。

class A:
    def is_class_A(self):
        print("We are in class A")


def alt_is_class_A(self):
    print("Nope")


class B(A):
    is_class_A = alt_is_class_A


class C(A):
    is_class_A = alt_is_class_A


class D(A):
    pass  # No override

分配也可以由装饰器处理:

def mod_it(cls):
    cls.is_class_A = alt_is_class_A


@mod_it
class B(A):
    pass


@mod_it
class C(A):
    pass


# No override
class D(A):
    pass

或通过A.__init_subclass__:

class A:
    def is_class_A(self):
        print("We are in class A")

    def __init_subclass__(cls, is_class_A=None):
        super().__init_subclass__()
        if is_class_A is not None:
            cls.is_class_A = is_class_A


def alt_is_class_A(self):
    print("Nope")


class B(A, is_class_A=alt_is_class_A):
    pass


class C(A, is_class_A=alt_is_class_A):
    pass


# No override 
class D(A):
    pass