1.偏函数partial

偏函数的作用类似装饰器,它可以在不改变原有函数的基础上,扩展函数的功能。在频繁调用某个函数时,某些参数是已知的固定值,如果不想每次都传入,可以利用partial来扩展这个函数。例如我们想要对一些数字求和,在求和的结果上再加100,那么常用的办法可以这么写:

def add(*args):
return sum(args) + 100

但是如果我们想要修改固定值100,那么就得改变add这个函数,下面使用partial实现:

from functools import partial


def add(*args):
return sum(args)


add_100 = partial(add, 100)
add_200 = partial(add, 200)

print(add_100(1, 2, 3)) # 106
print(add_200(1, 2, 3)) # 206

可以看到我们使用以原函数add固定值作为参数,传入parital类,返回了一个新函数,这样在调用新函数时,就不需要再传入固定值了。偏函数接收三个参数,它们可以扩展和覆盖原函数的参数:
func 需要被扩展的函数
*args 需要被固定的位置参数
**kwargs 需要被固定的关键字参数

类func = functools.partial(func, *args, **keywords)

2.管道符 |

python中的管道符 | 用于逻辑运算 ,它是通过内置魔法方法__ror__来实现的,因此我们可以重写这个方法来实现想要的效果。下面的例子中,我们重写的类A的__ror__方法,返回的是它接收的参数other和100的和,
可以看到,在执行1 | A()时,实际上是以1作为参数传入了A()实例的__ror__方法,这个语句的返回值就是__ror__方法的返回值

class A:
def __ror__(self, other):
return 100 + other


result = 1 | A()
print(result) # 101

3.用Python实现shell命令中的管道

python中的管道符通常使用在逻辑或的运算,如果要实现类似shell命令中的管道,就可以利用上面提到的偏函数以及重写__ror__方法,这个思路来自于v2ex上网友的分享,原贴地址:
https://www.v2ex.com/t/743574#reply112

下面是代码示例:

from functools import partial


class F(partial):
"""
partial接收3个参数,需要扩展的函数/不定长参数/关键字参数,返回一个新函数,
新函数会默认带上旧函数的参数,并且可以重写或扩展这些参数
"""
def __ror__(self, other):
"""
__ror__方法是python中管道符"|"对应的方法,接收的参数other就是"|"左边的值
例如类A实现了__ror__方法,那么在执行 x | A() 的时候,就是以x为参数传入类A的__ror__方法,执行的结果就是__ror__的返回值
"""
if isinstance(other, tuple):
return self(*other)
return self(other)


def add(*args, **kwargs):
return sum(*args)


def filter(*args):
return [i for i in args if i % 2 == 0]


result = (1, 2, 3, 4) | F(filter) | F(add)
print(result) # 6

可以看到,这里是继承了python的partial类,并重写了其__ror__方法,那么在执行(1, 2, 3, 4) | F(filter)时,就会以(1,2,3,4)为参数传入__ror__方法,在这个方法里面,self指向的是F(filter)这个对象。那么这个对象是什么呢,在第一节中我们知道,它实际上是一个扩展了filter函数的新函数,只不过这里没有额外传入其他参数也就没有进行扩展,因此self(*other)实际上是执行了filter(*other), 其结果就是[2, 4],这个结果又会作为参数传入F(add) 中,最终执行了add(*[2, 4])



Python

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!