Python方法重用样板循环结构,无需调用if子句n次[重复]

2eafrhcq  于 2023-03-11  发布在  Python
关注(0)|答案(2)|浏览(110)

此问题在此处已有答案

Is there a way to store a function in a list or dictionary so that when the index (or key) is called it fires off the stored function?(3个答案)
How does using a function (callback) as an argument to another function work in Python?(11个答案)
23小时前关门了。
我继承了一个遗留的代码库,其中有许多嵌套的for循环,类似于:

def func(infile, some_other_data, outfile, status_variable):
    with open(infile, 'r') as f:
        with open(outfile, 'w') as outf:
            for line in f:
                # parse line
                for element in some_other_data:
                    standard_function(line, element)
                    if status_variable == 'status_A':
                        function_A(line, element)
                    elif status_variable == 'status_B':
                        function_B(line, element)
                    # handle other possible status variables
                    outf.write(new_line)

这段代码与性能相关。为了加速它(除了其他更改之外),我想去掉所有被调用n*m次的if子句,测试表明这确实提高了10%。
为了做到这一点,我简单地复制和修改了主循环函数,为每个可能的状态变量,并相应地调用不同的函数。这有效地将if子句移出了循环。然而,这是非常丑陋的,使库大了4倍。
有没有一种(相当)简单的方法来处理这样的情况,我想重用样板循环,只是改变每次迭代所做的事情,而不是每次都处理条件?
我曾经尝试过动态返回循环函数的装饰器,根据状态变量调用不同的子函数,但是从可读性的Angular 来看,最终的结果看起来很糟糕,我绝不是pythonMaven,所以我可能忽略了一些有用的高级特性。
任何建议都将受到高度赞赏。

ljo96ir5

ljo96ir51#

理想情况下,您应该传递函数本身,而不是状态变量,但由于这是遗留代码,一个不更改接口的解决方案是设置函数字典,如下所示:

def func(infile, some_other_data, outfile, status_variable,
         status_functions={
             'status_A': function_A,
             'status_B': function_B,
         }
        ):

    try:
        status_function = status_functions[status_variable]
    except KeyError:
        status_function = lambda line, element: None

    with open(infile, 'r') as f, open(outfile, 'w') as outf:
        for line in f:
            # parse line
            for element in some_other_data:
                standard_function(line, element)

                status_function(line, element)
                # handle other possible status variables
                outf.write(new_line)
myzjeezk

myzjeezk2#

如果status_variable-〉function_name之间存在直接对应关系,并且所有调用都是正则的:function(line, element)可以传入函数:

def func(infile, some_other_data, outfile, function_from_status_variable):
    with open(infile, 'r') as f:
        with open(outfile, 'w') as outf:
            for line in f:
                # parse line
                for element in some_other_data:
                    standard_function(line, element)

                    function_from_status_variable(line, element)

                    outf.write(new_line)

计算一次,因此:

def calc_function(status_variable):
    if status_variable == 'status_A':
        return function_A
    elif status_variable == 'status_B':
        return function_B
    # other tests follow, plus handle an unknown value

最后像这样调用函数:

function = calc_function(status_variable)
func(infile, some_other_data, outfile, function)

相关问题