Python jQuery像语法一样,以模仿Unix壳管道



我不确定是否以前询问过这一点,但是我想知道如何实现python中的"定向"的语法来模仿unix shell Pipelines。特别是,如何使用可以产生,修改或消耗记录流的"普通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 的实现。

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

所以,我正在回答自己的问题,因为管道包装文档对我所陈述的问题不是很直观。特别是在实施完整的Unix Shell Pipe语义时。最后,关于一些常见的Unix技巧还有更多未解决的问题。

我们可以使用@pipe Decorator创建生产者作为Python发电机。请注意,这种类型的生产者只能是管道的第一个成员:

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

就像在Unix中一样,您可以定义一个变压器,该变压器有望改变其输入并生成输出:

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

我们可以使用"管道"语法连接生产商和变压器,该语法类似于Unix Shell Pipeline的语法:

producer() | transformer()

与unix shell不同,这不会产生输出;-(您可以写一个消费者,该消费者会消耗其输入并打印一些东西:

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

现在,连接将按预期工作:

producer() | transformer() | consumer()

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

producer(10) | transformer | consumer

我喜欢的另一个功能是shell的"这里文档":

[1,2,3,4] | transformer | consumer
在这种情况下,

[1,2,3,4]被解释为可能产生的一个值的序列,并且在管道中的下一个元素中"管道"。

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

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

现在最后在某些情况下,如何处理"管道"并不是很明显:

尚不清楚如何在外壳中进行等效的stdout合并:

(echo today ; date) | wc

也许使用" CAT"生产商,能够加入其所有峰值输入?

cat(echo("today"),date()) | ...

尚不清楚如何仅消耗管道的几个元素,然后继续使用另一个功能,例如在unix shell中:

cat /etc/passwd | (read line ; cat)

在这种情况下,阅读会消耗第一行,而猫会看到其余的。我们可以超载"("one_answers")"符号?

最新更新