用于重构for循环和嵌套if语句的组合的生成器

时间:2016-09-28 16:42:03

标签: python refactoring generator

下一个代码会扫描一些日志文件并选择包含某些特定字符的行。

with open(file) as input:
    for line in input:
        if 'REW' in line or 'LOSE' in line:
            <some optional code>
            if 'REW VAL' in line or 'LOSE INV' in line:
                <some code>

我在此编写了一些函数,但每个函数都包含这个重复的代码,所以我认为需要重构。我想我需要制作一台发电机。如何使这个生成器允许我更改括号中的代码?

2 个答案:

答案 0 :(得分:1)

对于任意代码,您可以做的最好的事情就是编写像

这样的函数
def foo(file, f1, f2):
    with open(file) as input:
        for line in input:
            if 'REW' in line or 'LOSE' in line:
                f1(line)
                if 'REW VAL' in line or 'LOSE INV' in line:
                    f2(line)

你需要对如何调用f1f2施加一些条件(在这里,我将它们定义为以行作为输入的函数)。

但这并不完全一般。例如,函数f1无法决定跳过下一个if语句并继续执行文件中的下一行。

答案 1 :(得分:1)

有时候重复并不是那么糟糕!

但无论如何你可以尝试这样的事情:

#!/usr/bin/env python
# script.py

def process_file(filename, func1, func2):
    with open(filename) as f:
        for line in f:
            if '1' in line:
                func1(line)
                if '2' in line:
                    func2(line)


def main():
    counters = {1: 0, 2: 0}
    def func1(line):
        # TODO Add some logic based on line value here
        counters[1] += 1
    def func2(line):
        counters[2] += 1
    process_file('table.csv', func1, func2)
    return counters


if __name__ == '__main__':
    print(main())

如果您有文件:

$ cat table.csv
1 just one
1 2 one and two
1
1
0
0
2
2 1
1 0 2
0

运行脚本:

python script.py

您将获得下一个输出:

{1: 6, 2: 3}

此外,您可以分析if语句的谓词:

def process_file(filename, func1, func2, predicate1, predicate2):
    with open(filename) as f:
        for line in f:
            if predicate1(line):
                func1(line)
                if predicate2(line):
                    func2(line)

def predicate1(line):
    return 'REW' in line or 'LOSE' in line

不要忘记选择好的功能名称!