python - Design pattern for implementing different "bundles" of functions in Python 3.6
问题描述
so I have a set of distance functions and respective calculations, e.g. average, comparison
and I want to be able to iterate over those different distances to compute their values/averages/whatevers, and make it easy to add new distances
Right now, I'm doing that by using nested dictionaries, however this depends on all the functions existing and working properly, so I was wondering whether there is a design pattern that solves that?
My first idea was a metaclass that defines which functions need to exist and classes that implement these functions. However, then there would be no meaningful instances of those Distance classes. My second idea then was defining a Distance class and have the functions as attributes of that class, but that seems bad style. Example for the second Idea:
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
this works (and also enforces the existence/maybe even properties of the functions), but as stated above feels like rather bad style. I do not plan to publish this code, its just about keeping it clean and organized if that is relevant. I hope the question is clear, if not pleas dont hesitate to comment and I will try to clarify.
EDIT: - @victor: Everything should be initially set. At runtime only selection should occur. - @abarnert Mostly habitual, also to restrict usage (np.mean needs to be called without axis argument in this example), but that should hopefully not be relevant since I'm not publishing this - @juanpa gonna look into that
解决方案
看来您需要的是简单的继承。因此,您创建了一个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 的鸭子类型方法(也适用于接口定义),您实际上并不需要实际定义的基类,但它有助于显示每个“空间”类的预期。
推荐阅读
- css - 为什么 nth-child 没有按预期工作?
- node.js - 从同一个浏览器获取不同的 sessionId
- ruby-on-rails - 在 Plesk-Server 上部署 Redmine 4.x:ArgumentError: string contains null byte
- pseudocode - 图片中使用的是什么编程语言?
- android - 如何在 react-native 上添加 android.support.v7.app
- bash - 如何归档文件名中日期超过 x 天的文件
- junit5 - ArchUnit 测试实际的分层架构
- qt - 遍历树项的所有子项
- java - 为什么几秒钟后我的刷新比开始后立即刷新要慢
- node.js - bulkWrite - 类型错误:无法在 applyTimestampsToUpdate 的数字 '0' 上创建属性 '$set' - mongoose 或 mongodb