处理“功能性” Python中副作用的正确方法

时间:2019-11-22 18:58:07

标签: python functional-programming generator

以下代码可以正常工作并且比标准python版本短(基本上每个filter语句节省1行,每个map节省1行,因此此代码比纯python短4行...代价为4 lambdas

    def xform_logfile(infile, ofile):
        with open(infile, "rt") as inf:
            with open(ofile, "wt") as of:
                m = map(lambda x: x.replace(":", " ").replace("\t", " ").strip().split(), inf)
                m = filter(lambda x: len(x) == 34, m)
                m = map(lambda
                        p: f"{p[0]} {p[1]}:{p[2]},{p[7]},{p[9]},{p[12]},{p[14]},{p[16]},{p[18]},{p[20]},{p[22]},{p[24]},{p[26]},{p[28]},{p[30]},{p[33]}\n",
                    m)
                m = map(lambda line: of.write(line), m)
                # Write new log
                of.write("DateTime, TempLeft, TempRight,Air Input, Driver , YA1, YA2, YB1, YB2, ZA1, ZA2, ZB1,ZB2,TempComp\n")
                list(m)

我对使用Python进行函数编程有些陌生,我想知道如何处理与文件IO相关的副作用,实际上只是处理不是纯序列转换的实际示例。

上面的代码将数据从自由格式的日志文件转换为可以由我们系统其他部分处理的csv文件。 (我只是显示代码以表明在写出数据之前还有一些功能步骤,我已经删除了异常处理,注释和其他过滤器。)

头有自己的行,这很尴尬,然后我需要将数据管道数据放入列表中,以使副作用发生。我意识到这就是使生成器通过管道提取数据的原因,但是它看起来很错误,因为它正在生成我将忽略的列表。我的替代方法是在这样的循环中写出最后一张地图:

    header = "DateTime,TempLeft,TempRight,Air Input,Driver,YA1,YA2,YB1,YB2,ZA1,ZA2,ZB1,ZB2,TempComp\n"
    of.write(header)    
    for line in m:
        of.write(line)

而不是使用map / lambda,但这也感觉不对。

有没有一种方法可以很好地将标头注入功能管道中?

这是强制生成器被处理的pythonic语法,还是像m.iterate()这样的内置函数(可以使生成器生效)?

在此示例中未显示,但是类似地,如果文件中的某行需要发出两行,就像向后过滤器一样,该怎么办? Lambda是否会返回一个可能被展平的列表或类似多行的字符串?

    map(lambda(x):"New Test" if x=="Test" else [x,"Old Test"])
    or
    map(lambda(x):"New Test" if x=="Test" else f"{x}\nOld Test")

0 个答案:

没有答案