si1*_*i14 18 python function-composition
前段时间我查看了Haskell文档,发现它的功能组合运算符非常好.所以我实现了这个小装饰:
from functools import partial
class _compfunc(partial):
def __lshift__(self, y):
f = lambda *args, **kwargs: self.func(y(*args, **kwargs))
return _compfunc(f)
def __rshift__(self, y):
f = lambda *args, **kwargs: y(self.func(*args, **kwargs))
return _compfunc(f)
def composable(f):
return _compfunc(f)
@composable
def f1(x):
return x * 2
@composable
def f2(x):
return x + 3
@composable
def f3(x):
return (-1) * x
@composable
def f4(a):
return a + [0]
print (f1 >> f2 >> f3)(3) #-9
print (f4 >> f1)([1, 2]) #[1, 2, 0, 1, 2, 0]
print (f4 << f1)([1, 2]) #[1, 2, 1, 2, 0]
Run Code Online (Sandbox Code Playgroud)
问题:没有语言支持,我们不能在内置函数或lambdas上使用这种语法,如下所示:
((lambda x: x + 3) >> abs)(2)
Run Code Online (Sandbox Code Playgroud)
问题:它有用吗?是否值得在python邮件列表上讨论?
函数组合不是Python中的超常用操作,尤其不是以明显需要组合运算符的方式.如果添加的东西,我不能肯定我喜欢的选择<<,并>>为Python,这是不那么明显对我来说,他们似乎是你.
我怀疑很多人会更熟悉一个函数compose,其顺序不成问题:compose(f, g)(x)意思是f(g(x)),与o数学和.Haskell中的顺序相同.Python试图避免在英语单词使用时使用标点符号,特别是当特殊字符没有广为人知的含义时.(对于那些看起来太有用而无法传递的事情,例如@为装饰者(非常犹豫)和*和**用于函数参数.)
如果你确实选择将它发送给python-ideas,你可能会赢得更多人,如果你能在stdlib或流行的Python库中找到一些实例,那么函数组合可以使代码更清晰,易于编写,可维护,或有效率.
你可以这样做reduce,虽然电话的顺序只是从左到右:
def f1(a):
return a+1
def f2(a):
return a+10
def f3(a):
return a+100
def call(a,f):
return f(a)
reduce(call, (f1, f2, f3), 5)
# 5 -> f1 -> f2 -> f3 -> 116
reduce(call, ((lambda x: x+3), abs), 2)
# 5
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1457 次 |
| 最近记录: |