小编Spa*_*ace的帖子

在抽象类方法的具体实现中检查 **kwargs。接口问题?

我正在尝试实现 Strategy 设计模式,以便为以模块化方式实现的底层算法创建一个接口。

目前,根据下面的代码,我有一个顶级/父抽象类 ( ParentAbstractStrategy),它定义了该strategy方法的基本接口。

我也有一个从这个抽象类 ( ChildAbstractStrategy)向下一级。

我有两个抽象类的原因是因为它们需要保存的属性;见__init__方法。 ChildAbstractStrategy是一种特殊情况,ParentAbstractStrategy因为它存储了一个附加属性:attr2。否则它的接口是相同的,如相同的strategy方法签名所见。

有时,我希望能够直接子类化ParentAbstractStrategy并实现strategy方法(请参阅ConcreteStrategyA),但有时我希望能够子类化ChildAbstractStrategy,因为需要额外的属性(请参阅ConcreteStrategyB)。

另一个复杂问题是,在任一抽象类的某些子类中,我希望能够处理strategy方法中的其他参数。这就是为什么我添加**kwargs到该strategy方法的所有签名中的原因,以便我可以根据具体情况将我想要的任何其他参数传递给子类。

这就产生了最后一个问题:这些额外的参数在子类中不是可选的。例如,在strategy方法ConcreteStrategyB我想肯定的是,来电者在第三个参数传递。我基本上是在滥用**kwargs提供可能应该是位置参数的内容(因为我不能给它们合理的默认值并且需要强制执行它们的存在)。

这种**kwargs在子类中用于“方法重载”的当前解决方案感觉非常混乱,我不确定这是否意味着类继承方案或接口设计存在问题,或两者兼而有之。

有没有办法以更简洁的方式实现这些设计目标。感觉就像我在这里错过了一些大图,也许类/界面设计很糟糕。也许为该strategy方法创建两个具有不同签名的不相交抽象类?

import abc


class ParentAbstractStrategy(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def __init__(self, attr1):
        self.attr1 = attr1

    @abc.abstractmethod
    def strategy(self, arg1, arg2, **kwargs):
        raise NotImplementedError


class ChildAbstractStrategy(ParentAbstractStrategy, metaclass=abc.ABCMeta):
    @abc.abstractmethod …
Run Code Online (Sandbox Code Playgroud)

python abstract-class strategy-pattern keyword-argument python-3.x

7
推荐指数
1
解决办法
1805
查看次数