我在Python工作。最近,我发现了一个名为fn的精彩小包。我一直在用它来进行功能组合。
例如,而不是:
baz(bar(foo(x))))
用fn,你可以写:
(F() >> foo >> bar >> baz)(x) .
当我看到这个时,我立刻想到了Clojure:
(-> x foo bar baz) .
但请注意,在Clojure中,输入位于左侧。我想知道这是否可能在python / fn。
答案 0 :(得分:10)
你不能复制确切的语法,但你可以做类似的事情:
def f(*args):
result = args[0]
for func in args[1:]:
result = func(result)
return result
似乎工作:
>>> f('a test', reversed, sorted, ''.join)
' aestt'
答案 1 :(得分:2)
虽然您可以获得F(x)(foo, bar, baz)
之类的内容,但您无法获得确切的语法。这是一个简单的例子:
class F(object):
def __init__(self, arg):
self.arg = arg
def __call__(self, *funcs):
arg = self.arg
for f in funcs:
arg = f(arg)
return arg
def a(x):
return x+2
def b(x):
return x**2
def c(x):
return 3*x
>>> F(2)(a, b, c)
48
>>> F(2)(c, b, a)
38
这与Blender的答案略有不同,因为它存储了参数,以后可以重复使用不同的函数。
这有点像普通函数应用程序的反面:不是预先指定函数并留下一些稍后要指定的参数,而是指定参数并保留稍后指定的函数。这是一个有趣的玩具,但很难想到为什么你真的想要这个。
答案 2 :(得分:1)
如果你想使用fn
,有点破解你可以更接近Clojure语法:
>>> def r(x): return lambda: x
>>> (F() >> r(x) >> foo >> bar >> baz)()
看看我如何在组合链的开头添加另一个函数,该函数在调用时将返回x
。这个问题是你仍然需要调用你的组合函数,只是没有任何参数。
我认为@Blender的答案是你最好的选择,试图在Python中模仿Clojure的线程函数。
答案 3 :(得分:0)
我想出了这个
event.stopPropagation
答案 4 :(得分:0)
这似乎适用于简单的输入。不确定复杂输入的工作是否值得,例如((42, 'spam'), {'spam': 42})
。
def compose(function, *functions):
return function if not functions else \
lambda *args, **kwargs: function(compose(*functions)(*args, **kwargs))
def rcompose(*functions):
return compose(*reversed(functions))
def postfix(arg, *functions):
return rcompose(*functions)(arg)
示例:
>>> postfix(1, str, len, hex)
'0x1'
>>> postfix(1, hex, len)
3
答案 5 :(得分:0)
我的compose
函数返回一个函数
def compose(*args):
length = len(args)
def _composeInner(lastResult, index):
if ((length - 1) < index):
return lastResult
return _composeInner(args[index](lastResult), index + 1)
return (lambda x: _composeInner(x, 0))
用法:
fn = compose(
lambda x: x * 2,
lambda x: x + 2,
lambda x: x + 1,
lambda x: x / 3
)
result = fn(6) # -> 5
答案 6 :(得分:0)
我明白你的意思。这没有道理。我认为这个python库 做得更好。
>>> from compositions.compositions import Compose
>>> foo = Compose(lambda x:x)
>>> foo = Compose(lambda x:x**2)
>>> foo = Compose(lambda x:sin(x))
>>> (baz*bar*foo)(x)