首先,感谢abersheeran ,他也是index.py的作者。看了这段代码不禁感叹:
天才就是99%的汗水+1%的灵感,但没有这1%的灵感那99%的汗水也是徒劳
大佬的思路我们还是看看就好,能理解就行了,创造出来还是很有难度的
代码
from functools import partial
class F(partial):
def __ror__(self, other):
return self(other)
# def __or__(self, other):
# return self(other)
y = range(10) | F(filter, lambda x: x % 2) | F(sum)
# y = F(sum) | (F(filter, lambda x: x % 2) | range(10))
print(y)
注释掉的部分是我狗尾续貂了一把,也是可以运行的。只不过看起来没那么管道
解读
我的解读可能有错误的地方,望批评指正。
这几行代码最天才的地方我觉得是继承了partical类,使得F object is callable
,这个可调用体现在self(other)
上。然后就是重写了__ror__
,这个思路是真的真实,天才的脑回路!!!
重新审视一下函数调用的过程
y
=
f
(
x
)
y = f(x)
y=f(x)
将
x
x
x当做输入,传递给
f
f
f,得到返回值,这个等价于代码中的self(other)
,而考虑到__ror__
运算符的特性,不熟悉一定要去看参考资料。正好可以得到想要的管道写法。由于|
运算符从左到右,再将y重新整理,得到如下代码:
y = range(10) | partial(filter, lambda x: x % 2)
y = y | partial(sum)
所以管道对应的函数为:
y = partial(filter, lambda x: x % 2)(range(10))
y = partial(sum)(y)
完整代码如下:
from functools import partial# as sys_partial
y = partial(filter, lambda x: x % 2)(range(10))
y = partial(sum)(y)
print(y)
修改代码,更好的理解
我觉得代码中让人难以理解的地方在于对F的命名,如果像下面这样,应该不难理解了。
from functools import partial as sys_partial
class partial(sys_partial):
def __ror__(self, other):
return self(other)
# def __or__(self, other):
# return self(other)
y = range(10) | partial(filter, lambda x: x % 2) | partial(sum)
# y = F(sum) | (F(filter, lambda x: x % 2) | range(10))
print(y)
参考资料
补充参考资料问答原文
Suppose you write your own integer class, and you want it to work with the built-in integers. You might define __or__
class MyInt(int):
def __or__(self, other):
# Not a recommended implementation!
return self | int(other)
so that you can write code like
# Because this is equivalent to MyInt.__or__(MyInt(6), 7)
MyInt(6) | 7
However, Python wouldn’t know what to do with
# First interpretation is int.__or__(7, MyInt(6))
7 | MyInt(6)
because int.__or__
wouldn’t know how to work with an instance of MyInt
. In such a case, Python swaps the order of the operands and tries
MyInt.__ror__(MyInt(6), 7)
that is, looks for the swapped version of the magic method in the class of the right-hand argument.