如何在python中实现可插拔函数的daisychaining?

2024-06-12 09:44:30 发布

您现在位置:Python中文网/ 问答频道 /正文

问题是:

1)假设我有一些测量数据(比如从我的电子设备中读取1Msample),我需要通过一个处理链来处理它们。在

2)此处理链由不同的操作组成,这些操作可以交换/省略/具有不同的参数。一个典型的例子是获取这些数据,首先通过查找表传递它们,然后进行指数拟合,然后乘以一些校准因子

3)现在,由于我不知道什么算法是最好的,我想在每个阶段评估最好的可能实现(例如,LUT可以通过5种方式产生,我想看看哪种是最好的)

4)我想把这些函数串联起来,这样我就可以构造一个“类”,它包含顶层算法,并拥有(即指向)子类,包含低级算法。在

我想用双链表生成序列,比如:

在myCaptureClass.addDataTreatment(pmCalibrationFactor(opt,pmExponentialFit(opt,pmLUT(opt)))

其中myCaptureClass是负责数据获取的类,它应该(在获取数据之后)触发顶级数据处理模块(pm)。这种处理将首先深入到底层子层(lut),在那里处理数据,然后是中间层(expofit),然后是顶层(califactors),并将数据返回给capture,后者将把数据返回给请求者。在

现在有几个问题:

1)网上到处都有人说在python中不应该使用双重链表 2) 这在我看来效率很低,因为数据向量很大,因此我更喜欢使用生成器函数的解决方案,但我不确定如何提供“类似插件”的机制。在

有人能给我一个提示,如何解决这个问题,使用'插件风格'和生成器,使我不需要处理向量的X兆字节的数据和处理他们'按要求',因为这是正确的,当使用生成器函数?在

非常感谢

大卫

问题补遗:

我似乎没有准确地表达自己。因此:数据由插入VME板条箱的外部硬件卡生成。它们在单个块传输中“获取”到python元组,该元组存储在myCaptureClass中。在

要应用的操作集实际上是在流数据上,由这个元组表示。甚至指数拟合是流操作(它是应用于每个样本的一组可变状态过滤器)。在

我错误地显示了参数'opt'是为了表示每个数据处理类都有一些配置数据,这些数据处理类修改了用于操作数据的方法的行为。在

我们的目标是在myCaptureClass中引入一个daisychained类(而不是函数),当用户请求数据时,我们通常将“原始”数据处理成最终形式。在

为了“节省”内存资源,我认为使用生成器函数提供数据可能是个好主意。在

从这个角度来看,与我想要做的最接近的匹配显示在bukzor代码中。我更喜欢用类实现而不是函数,但我想这只是在特定类中实现调用运算符的一个装饰性的东西,它实现了数据操作。。。。在


Tags: 数据函数算法插件参数指数向量省略
3条回答

{pypi>从模块中获取。它有一个compose函数来组合两个可调用项。这样,就可以将函数链在一起。在

该模块和functool都为部分应用提供了partial函数。在

您可以像使用其他函数一样在生成器表达式中使用组合函数。在

我想你就是这样做的。我想这是不完整的,因为我不完全理解你的问题陈述。请告诉我我做错了什么:)

class ProcessingPipeline(object):
    def __init__(self, *functions, **kwargs):
        self.functions = functions
        self.data = kwargs.get('data')
    def __call__(self, data):
        return ProcessingPipeline(*self.functions, data=data)
    def __iter__(self):
        data = self.data
        for func in self.functions:
            data = func(data)
        return data

# a few (very simple) operators, of different kinds
class Multiplier(object):
    def __init__(self, by):
        self.by = by
    def __call__(self, data):
        for x in data:
            yield x * self.by

def add(data, y):
    for x in data:
        yield x + y

from functools import partial
by2 = Multiplier(by=2)
sub1 = partial(add, y=-1)
square = lambda data: ( x*x for x in data )

pp = ProcessingPipeline(square, sub1, by2)

print list(pp(range(10)))
print list(pp(range(-3, 4)))

输出:

^{pr2}$

我不知道你到底想要什么,我觉得我应该指出,你可以把你想要的东西放进清单理解:

l = [myCaptureClass.addDataTreatment(
          pmCalibrationFactor(opt, pmExponentialFit (opt, pmLUT (opt))))
     for opt in data]

将创建已通过组合函数传递的新数据列表。在

或者你可以为循环创建一个生成器表达式,这不会构造一个全新的列表,它只会创建一个迭代器。我不认为这种方式与仅仅在循环体中处理数据相比有任何优势,但是我们可以看看:

^{pr2}$

或者opt是数据吗?在

相关问题 更多 >