在 "功能性 "python中处理副作用的正确方法

问题描述 投票:1回答:1

下面的代码可以用,而且比标准的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有自己的行,然后我需要把数据管道的数据放到一个列表中,才能发生副作用。 我意识到这是使生成器通过管道拉动数据的原因,但它看起来就不对了,因为它正在制作一个我要忽略的列表。 我的替代方案是像这样在循环中写出最后一张地图。

    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)

而不是使用maplambda,但这也是错误的。

有没有一种方法可以很好地将头注入到函数管道中?

是用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")
python functional-programming generator
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.