我使用Python工作。最近,我發現了一個叫fn的精美小包。我一直在使用它來進行函數組合。Python中更好的函數組合
,而不是例如:
baz(bar(foo(x))))
與Fn鍵,你可以寫:
(F() >> foo >> bar >> baz)(x) .
當我看到這個,我馬上想到的Clojure的:
(-> x foo bar baz) .
但請注意,在Clojure中,輸入是在左邊。我想知道這是否可能在python/fn中。
我使用Python工作。最近,我發現了一個叫fn的精美小包。我一直在使用它來進行函數組合。Python中更好的函數組合
,而不是例如:
baz(bar(foo(x))))
與Fn鍵,你可以寫:
(F() >> foo >> bar >> baz)(x) .
當我看到這個,我馬上想到的Clojure的:
(-> x foo bar baz) .
但請注意,在Clojure中,輸入是在左邊。我想知道這是否可能在python/fn中。
你不能複製確切的語法,但你可以做類似的東西:
def f(*args):
result = args[0]
for func in args[1:]:
result = func(result)
return result
似乎工作:
>>> f('a test', reversed, sorted, ''.join)
' aestt'
你不能說確切的語法,雖然可以得到像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的回答有點不同,因爲它存儲的說法,以後可以具有不同功能的重新使用。
這有點像正常函數應用程序的反面:不是先指定函數,而是稍後指定一些參數,然後指定參數並稍後指定函數。這是一個有趣的玩具,但很難想象你爲什麼要這麼做。
如果你想使用fn
,一個小黑客,你可以得到一個有點接近Clojure的語法:
>>> def r(x): return lambda: x
>>> (F() >> r(x) >> foo >> bar >> baz)()
看我怎麼在組合鏈的開始,將只返回x
增加了一個功能當被調用時。這個問題是你仍然需要調用你的組合函數,只是沒有任何參數。
我認爲@ Blender的答案是您最好的選擇,試圖在Python中模擬Clojure的線程函數。
我想出了這個
def _composition(arg, *funcs_and_args):
"""
_composition(
[1,2,3],
(filter, lambda x: x % 2 == 1),
(map, lambda x: x+3)
)
#=> [4, 6]
"""
for func_and_args in funcs_and_args:
func, *b = func_and_args
arg = func(*b, arg)
return(arg)
這似乎爲簡單的輸入工作。不確定值得花費在複雜輸入上,例如((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
雖然操作符重載行爲是有趣的,對我來說這似乎只是一件壞事,在實際的代碼做。 –
如果這就是你所要求的,沒有辦法在Python中使用精確的語法。您可以通過各種方式對其進行近似。什麼對你來說很重要? – BrenBarn
保持流量從左到右。目前,對組合函數的爭論已經結束。如果我可以寫F()>> x >> foo >> bar >> baz或類似的話,它會更清晰。 –