如果两个 类 扩展不同 类 如何避免重复代码

How to avoid duplicate code if two classes extending different classes

我有两个 classes,它们扩展了两个不同的基础 classes。这些 classes 设置自定义环境。

classes 中共有三种方法:prepare()setup()teardown()。 每个方法都会覆盖基础 class 方法。 (他们也有 super() 个调用。)另外 ExtendedBase 扩展了 Base.

第一个class:

ClassA(Base):
    def __init__(self, args):
        super().__init__(args)

        self._private = OtherClass()

    def prepare(self, args):
        super().prepare(args)
        self._private.prepare()

    def setup(self, args):
        super().setup(args)
        self._private.setup(self._smth, args)

    def teardown(self):
        self._private.teardown()
        super().teardown()

第二个class:

ClassB(ExtendedBase):
    def __init__(self, args):
        super().__init__(args)

        self._private = OtherClass()

    def prepare(self, args):
       super().prepare(args)
       self._private.prepare()

    def setup(self, args):
       super().setup(args)
       self._private.setup(self._smth, args)

    def teardown(self):
       self._private.teardown()
       super().teardown()

这是避免重复方法的方法吗? 我考虑过 Environment class 的多重继承,它将包含重复的方法,但我对如何实现它以及它是否是一个好主意感到困惑。

已编辑:不幸的是我无法对 classes 层次结构做任何事情。 ClassAClassB 应该继承相应的 classes 并覆盖或使用父方法。

这看起来很像使用 class mixin 的典型案例:

class BuildMixin:
    def __init_(self, args):
        super().__init__(args)
        self._private = OtherClass()

    def prepare(self, args):
        super().prepare(args)
        self._private.prepare()

    def setup(self, args):
        super().setup(args)
        self._private.setup(self._smth, args)

    def teardown(self):
        self._private.teardown()
        super().teardown()

class ClassA(BuildMixin, Base):
    pass

class ClassB(BuildMixin, ExtendedBase):
    pass

出于说明目的,这里有一堆虚拟 classes,它们遵循您的示例并使用 mixin。从你的问题中不清楚 OtherClass 应该是什么,但它似乎也有 prepareteardownsetup 方法:

class OtherClass:
    def prepare(self,arg):
        print('OC perparing')
    def teardown(self):
        print('OC tearing down')
    def setup(self, smth, args):
        print('OC setting up')

class Base:
    def __init__(self, args):
        print('Base init')
        self._smth=args
    def prepare(self,arg):
        print('Base perparing')
    def teardown(self,):
        print('base tearing down')
    def setup(self,args):
        print('base setting up')

class ExtendedBase:
    def __init__(self, args):
        print('ExtBase init')
        self._smth=args
    def prepare(self, arg):
        print('ExtBase perparing')
    def teardown(self):
        print('ExtBase tearing down')
    def setup(self, arg):
        print('ExtBase setting up')

class BuildMixin:
    def __init__(self, arg):
        super().__init__(arg)
        self._private = OtherClass()
    def prepare(self, args):
        super().prepare(args)
        self._private.prepare(args)

    def setup(self, args):
        super().setup(args)
        self._private.setup(self._smth, args)

    def teardown(self):
        self._private.teardown()
        super().teardown()

class  ClassA(BuildMixin, Base):
    pass

class ClassB(BuildMixin, ExtendedBase):
    pass
    
a = ClassA(1)
# prints:
# Base init
b = ClassB(1)
# prints:
# ExtBase init
a.prepare(1)
# prints:
# Base perparing
# OC perparing
b.prepare(1)
# prints:
# ExtBase perparing
# OC perparing

# and so on...