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

问题描述

我有两个类扩展了两个不同的基类。这些类设置自定义环境。

这两个类共有三种方法prepare()setup()teardown()。 每个方法都覆盖基类方法。 (他们也有super()个电话。)另外,ExtendedBase扩展了Base

头等舱

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()

第二堂课

ClassB(ExtendedBase):
    def __init__(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类的多重继承,该类将包含重复的方法,但是对于如何实现它以及是否完全是个好主意感到困惑。

编辑:不幸的是,我无法对类层次进行任何处理。 ClassAClassB应该继承相应的类并覆盖或使用父级的方法

解决方法

这看起来很像使用类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

出于说明目的,这里有一些虚拟类,它们遵循您的示例并使用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)

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

class  ClassA(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...