具有函数特定参数的Python代码模块化

问题描述

我的代码包含多行嵌套的for循环。我想通过将代码放入类似于下面的do_for_each函数的自己的函数中,来尝试减少嵌套的for循环的数量。在嵌套的for循环中,我想调用一个函数。下面是一个工作示例:

def do_for_each(self,func,h,w,init_data):
        for x in range(1,h):
            for y in range(1,w):
                init_data[x,y] = func(x,y)
        return init_data

def calculate_land_neighbours(self,x,y):
        return self.lscape[x-1,y] + self.lscape[x+1,y] + self.lscape[x,y-1] + self.lscape[x,y+1]

ouput = self.do_for_each(self.calculate_land_neighbours,self.h+1,self.w+1,data)

但是,当在do_for_each调用函数未采用参数xy而是采用另一个变量时,就会出现我的问题。例如,一个功能将如下所示:

def add_to_density_array(self,seed):
        if seed == 0:
            return 0
        else:
            return random.uniform(0,5.0)

output2 = self.do_for_each(self.add_to_density_array,data,seed)

要使其正常运行,我需要将do_for_each函数修改为:

def do_for_each(self,init_data,seed):
        for x in range(1,y] = func(seed)
        return init_data

有人会建议我保留do_for_each函数的模块化代码,但是在do_for_each调用不具有相同输入参数的函数吗?

解决方法

从根本上说,您的两个do_for_each函数只是完全不同。它们根本没有执行相同的转换-一种是根据xy索引来更改矩阵项,而另一种则不。

我会考虑在这里使用不同的抽象。

也就是说,您可以无需更改原始do_for_each就可以完成这项工作:传递包装add_to_density_array的lambda,而不是直接传递后者:

add_to_density = lambda x,y: self.add_to_density_array(seed)
output2 = self.do_for_each(add_to_density,self.h+1,self.w+1,data)
,

您可以将seed的默认参数用作None,并检查其是否退出并相应地操作:

def do_for_each(self,func,h,w,init_data,seed=None):
    for x in range(1,h):
        for y in range(1,w):
            # If no seed provided
            if seed is None:
                init_data[x,y] = func(x,y)
            # Else,seed provided - use it
            else:
                init_data[x,y] = func(seed)
    return init_data

这具有向后兼容“旧” do_for_each(self,init_data)的优势。

,

您可以尝试重载函数,这是一个可能的解决方案。您可以在这里阅读更多内容-https://www.geeksforgeeks.org/python-method-overloading/

def do_for_each(self,seed=None):
    if seed==None:
        for x in range(1,h):
            for y in range(1,w):
                init_data[x,y)
        return init_data
    else:
        for x in range(1,y] = func(seed)
        return init_data