1

我创建了一个MyClass包含大量模拟数据的类。类对具有相似结构的不同模拟的模拟结果进行分组。可以使用MyClass.get(foo)方法检索结果。它返回一个带有模拟ID/数组对的字典,数组是foo每个模拟的值。

现在我想在我的类中实现一个方法,将任何函数应用于foo. 它应该返回一个带有simulationID/function(foo) 对的字典。

对于不需要额外参数的函数,我发现以下解决方案非常令人满意(总是欢迎评论:-)):

def apply(self, function, variable):
    result={}
    for k,v in self.get(variable).items():
        result[k] = function(v)
    return result

但是,对于需要额外参数的函数,我看不到如何以优雅的方式进行操作。一个典型的操作是将foowithbar作为 x 值的积分,例如np.trapz(foo, x=bar),其中foobar都可以用MyClass.get(...)

我在想这个方向:

def apply(self, function_call):
    """
    function_call should be a string with the complete expression to evaluate
    eg: MyClass.apply('np.trapz(QHeat, time)')

    """
    result={}
    for SID in self.simulations:
        result[SID] = eval(function_call, locals=...)

    return result

问题是我不知道如何传递本地映射对象。或者,也许我看错了方向。预先感谢您的帮助。

罗尔

4

2 回答 2

2

你有两种方法。首先是使用functools.partial

foo = self.get('foo')
bar = self.get('bar')
callable = functools.partial(func, foo, x=bar)
self.apply(callable, variable)

第二种方法是使用部分使用的相同技术,您可以定义一个接受任意参数列表的函数:

def apply(self, function, variable, *args, **kwds):
    result={}
    for k,v in self.get(variable).items():
        result[k] = function(v, *args, **kwds)
    return result

请注意,在这两种情况下,函数签名都保持不变。我不知道我会选择哪一个,也许是第一个案例,但我不知道你正在研究的背景。

于 2012-05-10T16:37:05.337 回答
1

我试图按照我猜测的方式重新创建类结构(的相关部分),它是在你身边设置的(如果你可以提供一个简化的代码示例供人们玩/测试,它总是很方便)。

我认为您正在尝试做的是将变量名称转换为从类中获得的变量,然后在传入的函数中使用这些变量。除此之外,由于每个变量实际上是一个带有键 (SID) 的值字典,因此您希望结果是一个结果字典,并将函数应用于每个参数。

class test:
    def get(self, name):
        if name == "valA":
            return {"1":"valA1", "2":"valA2", "3":"valA3"}
        elif name ==  "valB":
            return {"1":"valB1", "2":"valB2", "3":"valB3"}
    def apply(self, function, **kwargs):
        arg_dict = {fun_arg: self.get(sim_args) for fun_arg, sim_args in kwargs.items()}
        result = {}
        for SID in arg_dict[kwargs.keys()[0]]:
            fun_kwargs = {fun_arg: sim_dict[SID] for fun_arg, sim_dict in arg_dict.items()} 
            result[SID] = function(**fun_kwargs)
        return result

def joinstrings(string_a, string_b):
    return string_a+string_b

my_test = test()
result = my_test.apply(joinstrings, string_a="valA", string_b="valB")
print result

因此,apply 方法获取一个参数字典,获取每个参数的类特定数据,并使用这些 (arg_dict) 创建一个新的参数字典。

SID 键是从此 arg_dict 获得的,并且对于其中的每一个,都会计算一个函数结果并将其添加到结果字典中。

结果是:

{'1': 'valA1valB1', '3': 'valA3valB3', '2': 'valA2valB2'}

可以通过多种方式更改代码,但我认为这将是最易读的。当然可以加入字典而不是使用第一个元素中的 SID 等。

于 2012-05-11T07:09:34.857 回答