如何在 Python 中制作我自己的映射类型



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

现在我想在我的类中实现一个方法,以将任何函数应用于foo的所有数组。 它应该返回一个带有模拟ID/函数(foo(对的字典。

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

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

但是,对于需要额外参数的函数,我看不出如何以优雅的方式做到这一点。 一个典型的操作是将foobar积分为 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

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

罗尔

你有两种方法。第一种是使用 functools.partial:

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

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

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

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

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

我认为您要做的是将变量名称转换为从类中获得的变量,然后在传入的函数中使用这些变量。除此之外,由于每个变量实际上是具有键 (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 等。

相关内容

最新更新