Python JQUERY类似于模仿Unix Shell Pipelines的语法

时间:2017-09-14 06:20:21

标签: python unix

我不确定之前是否曾经问过这个问题,但我想知道如何在python中实现类似于set set的语法来模仿UNIX SHELL管道。 特别是,如何使用可以生成,修改或使用记录流的“普通python函数”,并且可以使用“。”将它们粘合在一起。操作

一个简单的例子,假设python函数像Unix程序:

在unix中我们可以做到:

    ls | egrep '^a' | wc -l

计算当前目录中以“a”开头的文件。 怎么样:

    from  unixtools import *
    ls().egrep('^a').wc(countLines=True)

并且ls的实现可以像生成器一样:

    @pipeline
    def ls():
       for file in glob.glob("*"):
          yield file

我省略了明显的胶水代码,这样就可以将 ls 与管道的其他“命令”连接起来。

@pipeline 是尝试使用装饰器将普通python函数转换为管道协议的成员。

我意识到这可以使用python的传统语法来完成,它的可读性较低,迫使你反向编写,而且更容易出错:

     wc(countLines=True,input=egrep("^a",input=ls()))

我想我们可以研究python pyquery 的实现来搞清楚。

1 个答案:

答案 0 :(得分:0)

显然,python管道包非常接近我的要求,我不知道它。

所以,我正在回答我自己的问题,因为管道包文档对我说明的问题不是很直观。特别是在实现完整的unix shell管道语义时。最后,关于一些常见的unix技巧还存在一些尚未解决的问题。

我们可以使用@Pipe装饰器创建一个生成器作为python生成器。 请注意,这种类型的生产者只能是管道的第一个成员:

SharedModule

与在Unix中一样,您可以定义一个变换器,它可以转换输入并生成输出:

@NgModule({
  imports: [
    // ...
    SharedModule
  ],
  declarations: [
    // ...
  ],
  exports: [
    // ...
  ]
})
export class AppModule {
  // ...
}

我们可以使用“管道”语法来连接生产者和变换器,这类似于Unix Shell管道的语法:

from pipe import Pipe
@Pipe
def producer(arg=10):
    for x in range(arg):
         yield x

与Unix shell不同,这不会产生任何输出;-( 您可以编写消费者,消费者输入并打印一些内容:

@Pipe
def transformer(iterable, arg=2):
    for x in iterable:
         if x % arg == 0: yield x*2

现在连接将按预期工作:

producer() | transformer()

有趣的是,在第二个或更多个管道元素上,我们可以省略括号,只使用管道函数的名称:

@Pipe
def consumer(iterable):
    for x in iterable:
        print(x)

我喜欢的另一个功能,相当于SHELL“here document”:

producer() | transformer() | consumer()

在这种情况下,[1,2,3,4]被解释为生成器可以生成的值序列,并且“管道”到管道中的下一个元素。

我们当然可以收集管道结果:

producer(10) | transformer | consumer

现在终于有些情况下如何处理“管道”并不是很明显:

目前尚不清楚如何在SHELL中进行等效的stdout合并:

[1,2,3,4] | transformer | consumer

也许使用“cat”生成器,能够连接所有可迭代的输入?

a = [1,2,3,4] |  transformer | consumer

还不清楚如何只使用管道的一些元素,然后继续使用另一个函数,就像在UNIX SHELL中一样:

(echo today ; date) | wc

在这种情况下,read消耗第一行,cat看到其余的行。我们可以重载“(”和“)”符号吗?