类似pythonjquery的语法来模拟unixshell管道

2024-06-01 05:32:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我不确定以前是否有人问过这个问题,但我想知道如何在python中实现类似“面向集”的语法来模拟unixshell管道。 特别是,如何使用“普通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尝试使用decorators将普通python函数转换为管道协议的成员。你知道吗

我意识到这可以通过使用python的传统语法来实现,它的可读性较差,迫使您以相反的方式编写,而且更容易出错:

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

我想我们可以研究pythonpyquery的实现来解决这个问题。你知道吗


Tags: 函数trueinput管道pipeline面向记录语法
1条回答
网友
1楼 · 发布于 2024-06-01 05:32:08

显然,python管道包非常接近于我所要求的,而我并没有意识到这一点。你知道吗

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

我们可以使用@Pipe decorator创建一个producer作为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

我们可以使用“pipe”语法连接producer和transformer,这类似于Unix Shell管道:

producer() | transformer()

与unixshell不同,它不产生任何输出-( 您可以编写一个消费者,它使用其输入并打印一些内容:

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

现在连接将按预期工作:

producer() | transformer() | consumer()

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

producer(10) | transformer | consumer

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

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

在这种情况下,[1,2,3,4]被解释为一系列可能产生的值,它被“管道”输送到管道中的下一个元素。你知道吗

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

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

现在终于有一些案例不太清楚如何处理“管道”:

目前尚不清楚如何在SHELL中实现stdout合并:

(echo today ; date) | wc

也许使用一个“猫”生产者,能够连接它的所有iterable输入?你知道吗

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

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

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

在本例中,read使用第一行,cat看到其余的行。我们能重载“(”和“)”符号吗?你知道吗

相关问题 更多 >