为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

噜噜哒 2021-12-29 20:30:39
我继承了一个遗留代码库,里面有很多嵌套的 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 专家,所以我可能会忽略一些在这里可能有用的方便的高级功能。任何建议都非常感谢。
查看完整描述

2 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

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


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)


查看完整回答
反对 回复 2021-12-29
?
绝地无双

TA贡献1946条经验 获得超4个赞

如果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)


查看完整回答
反对 回复 2021-12-29
  • 2 回答
  • 0 关注
  • 189 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号