在Python 3.6中实现不同功能“捆绑”的设计模式

时间:2018-08-14 15:37:40

标签: python design-patterns python-3.6

所以我有一组距离函数和相应的计算,例如平均,比较

并且我希望能够遍历这些不同的距离以计算其值/平均值/任何值,并轻松添加新的距离

现在,我正在使用嵌套字典来执行此操作,但是这取决于现有的所有功能并能正常工作,所以我想知道是否存在一种可以解决该问题的设计模式?

我的第一个想法是一个元类,它定义需要存在的功能以及实现这些功能的类。但是,这些Distance类将没有有意义的实例。 然后,我的第二个想法是定义一个Distance类,并将这些函数作为该类的属性,但是这似乎很糟糕。 第二个想法的示例:

class Distance:
    def __init__(self, distf, meanf):
        self.distf = distf
        self.meanf = meanf

    def dist(self, x1,x2):
        return self.distf(x1,x2)

    def mean(self, xs):
         return self.meanf(xs)

    d = Distance(lambda x,y: abs(x-y), np.mean)

    d.dist(1,2) ##returns 1 as expected
    d.dist([1,2]) ## returns 1.5 as expected

这有效(并且也强制了功能的存在/甚至是功能的属性),但是如上所述,这感觉很不好。我不打算发布此代码,如果相关的话,仅用于保持代码整洁有序。 我希望这个问题是明确的,如果没有,请不要犹豫,我将尽力澄清。

编辑: -@victor:应该先设置好所有内容。在运行时,仅应进行选择。 -@abarnert通常是习惯性的,也是为了限制使用(在此示例中,需要在不使用axis参数的情况下调用np.mean),但由于我不打算发布此文件,因此希望它不相关 -@juanpa将会调查

1 个答案:

答案 0 :(得分:2)

您似乎需要简单的继承。 因此,您创建了一个基本类BaseSpace,它基本上是一个接口:

from abc import ABC

class BaseSpace(ABC):
    @staticmethod
    def dist(x1, x2):
        raise NotImplementedError()

    @staticmethod
    def mean(xs):
        raise NotImplementedError()

然后,您只需使用所需功能的所有不同组合继承此接口,即可在类内部(如果仅使用它们一次)或外部实现方法,然后在类定义中分配它们:

class ExampleSpace(BaseSpace):
    @staticmethod
    def dist(x1, x2):
        return abs(x1 - x2)

    mean = staticmethod(np.mean)

由于Python的duck typing方法(也适用于接口定义),您实际上并不需要实际定义的基类,但是它有助于显示每个“ Space”类的期望