六行代码实现 Python 管道

2021-01-10 17:14:24 +08:00
 abersheeran

不多说,直接上代码。

from functools import partial

class F(partial):
    def __ror__(self, other):
        if isinstance(other, tuple):
            return self(*other)
        return self(other)

使用样例。

range(10) | F(filter, lambda x: x % 2) | F(sum)

更详细的前因后果介绍,可以看 https://aber.sh/articles/Python-Pipe/ ,实在是懒得复制到 V2EX 调样式了。有兴趣的就看看,没兴趣的就复制代码去用就完事。

小小的得瑟一下,这是最近几天写的最满意、最有用的代码。妙手偶得之~

13707 次点击
所在节点    Python
122 条回复
no1xsyzy
2021-01-12 23:58:50 +08:00
@yueyoum 你先做个能够同时符合你这 6 条里两条的语言出来吧。
这六条,两两冲突……
black11black
2021-01-13 09:12:26 +08:00
震惊于还有这种写法

看了楼上的讨论,对我个人而言感觉最合适的语法是

```
a = PIPE | range(10) | (map , str) | END
```

这种格式,有初始化时不需要显式新建对象,感觉有时间可以封装一下
black11black
2021-01-13 09:15:25 +08:00
我觉得直接封装函数无意义,比如 PIPE 并不直接返回结果而是创建一个可供输入的对象,我并不常用这种功能。如果有需要我更愿意另外显式封装函数
abersheeran
2021-01-13 09:18:56 +08:00
@black11black 如果是这么用呢?

range(100) | Filter(lambda x: x % 2) | Map(lambda x: x * x) | Reduce(lambda x, y: x + y)

https://github.com/abersheeran/only-pipe/discussions/1
black11black
2021-01-13 09:44:00 +08:00
@abersheeran 这么用的话使用上就很舒服了,但是这些 filter map 之类的是自建类吧,感觉不是那么的完美,像 LZ 这个实现,每个函数外面还要加个 F (),感觉也很不 pythonic 。我大概把我上面的想法写了一下是这样

https://gist.github.com/GoodManWEN/351fe48e24d61b8a62adef3e4460259e

> i = PIPE | range(10) | (map , lambda x:x + 1) | list | set | END
> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
> func = lambda x: PIPE | range(x) | (map , lambda x:x + 1) | list | set | END
> func(5)
> {1, 2, 3, 4, 5, 6}
SmiteChow
2021-01-13 11:33:03 +08:00
管道应该面向生成器,如果不是则逻辑的实质为不同函数的流式调用,流式调用必须要有 schema 声明以及对应的解释 shema 逻辑才对的。
SmiteChow
2021-01-13 11:34:28 +08:00
所以你把管道和流式调用弄混了
SmiteChow
2021-01-13 11:45:35 +08:00
但这也能说明你的 python 功力不错,赞。
abersheeran
2021-01-13 11:56:43 +08:00
@SmiteChow 我对管道的理解来自于 Shell,这里指的也是 Shell 那种管道。
aguesuka
2021-01-13 12:41:00 +08:00
管道是一个优先级较低的左结合中缀运算符。(表达式 运算符 函数) 相当于 (函数 表达式)。作为中缀表达式,它的两个类型不同,不满足交换和结合律,不能保证参数 imutable 。我觉得不适合出现在常规的编程语言中。
而且实现是右结合的,如果左边实现了 lor 应该会有问题。
lyzh
2021-01-13 17:35:07 +08:00
@SmiteChow 这里没问题,Filter 和 map 这类本身就可以被柯里化绑定成一个单参函数,然后由管道加入调用流
lyzh
2021-01-13 17:36:25 +08:00
@aguesuka 管道中不宜出现副作用,这和“管道”的定义本身就是相悖的
SmiteChow
2021-01-14 10:32:48 +08:00
@abersheeran Shell 的管道是可以多次读写的(对应过来就是生成器),你可以细心观察一下

```
echo 1 ; sleep 1 ; echo 2|cat
```
SmiteChow
2021-01-14 10:37:49 +08:00
@lyzh 对的,你举例是将生成器的职责落到了“管道”两端的子操作上去,但这更加说明“管道”不是真正意义上的管道,仅仅是流式调用。
yueyoum
2021-01-14 18:30:21 +08:00
@no1xsyzy 我并没有说 好语言 是要全部占完, 而是 python 一样都沾不上
no1xsyzy
2021-01-14 20:12:03 +08:00
@yueyoum
1. 你看来中文运用不是特别好。
“什么是好语言:”然后罗列特点 123456,然后说好语言不需要全部占完…… 挺微妙的。

2. 你看来中文理解不是特别好。
什么叫“两两冲突”?不是说不能全部占完,你能占两样就是登天难。

3. 我只好建议你抛弃中文了,一方面根据 1. 2. 中文对你似乎有点困难。
二来,让我稍微改下你的原话 ——
什么是好语言:
123456
中文 一样都没占上
连最基本的 语言特性, 我敢说 这个帖子里 没有一个人 完全掌握了 中文 的特性
所以, 自己玩玩可以

想了想,我建议你使用拉丁语
yueyoum
2021-01-19 12:12:54 +08:00
@no1xsyzy

你自己 去小学重修语文吧

或者看看 一句名言: better than nothing

已经 block 了, 不用劳烦你打字回复了
no1xsyzy
2021-01-19 13:16:58 +08:00
@yueyoum 打滚打得好,当个猪妈宝
css3
2021-01-26 20:36:48 +08:00
简介,好用,但没懂是怎么解析出来 | 这个符号的
css3
2021-01-26 20:39:12 +08:00
就是或运算符吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/743574

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX