pythonic方式重用样板循环结构而不调用if子句n次

我继承了一个遗留代码库,里面有很多嵌套的 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 倍。


是否有一种(相当)简单的 pythonic 方法来处理这种情况,我想重用样板循环,只是改变每次迭代所做的事情,而不是每次都处理条件?


我一直在玩装饰器,根据状态变量动态返回循环函数调用不同的子函数,但从可读性的角度来看,最终结果看起来很糟糕。我绝不是 Python 专家,所以我可能会忽略一些在这里可能有用的方便的高级功能。


任何建议都非常感谢。


噜噜哒
浏览 190回答 2
2回答

倚天杖

理想情况下,您将传递函数本身而不是状态变量,但由于这是遗留代码,因此不更改接口的一种解决方案是设置函数字典,如下所示: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)

绝地无双

如果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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python