在Clojure中我可以这样做:
(-> path
clojure.java.io/resource
slurp
read-string)
而不是这样做:
(read-string (slurp (clojure.java.io/resource path)))
这在Clojure术语中称为线程 ,有助于摆脱大量括号。
在Python中,如果我尝试使用像map
,any
或filter
这样的功能结构,我必须将它们相互嵌套。在Python中是否有一个构造,我可以在Clojure中做类似于线程化(或管道化)的操作?
我没有找到功能齐全的版本,因为Python中没有宏,我只是想在我用Python进行函数式编程时取消很多括号。
修改:我最终使用支持pipe
的{{3}}。
答案 0 :(得分:6)
这是@deceze的想法的简单实现(尽管,正如@Carcigenicate指出的那样,它最多只是一个部分解决方案):
import functools
def apply(x,f): return f(x)
def thread(*args):
return functools.reduce(apply,args)
例如:
def f(x): return 2*x+1
def g(x): return x**2
thread(5,f,g) #evaluates to 121
答案 1 :(得分:1)
我想把它变为极端,并动态地完成所有工作。
基本上,下面的Chain类允许您将函数链接在一起,类似于Clojure的->
和->>
宏。它支持线程化到第一个和最后一个参数。
按此顺序解决功能:
代码:
class Chain(object):
def __init__(self, value, index=0):
self.value = value
self.index = index
def __getattr__(self, item):
append_arg = True
try:
prop = getattr(self.value, item)
append_arg = False
except AttributeError:
try:
prop = locals()[item]
except KeyError:
prop = getattr(__builtins__, item)
if callable(prop):
def fn(*args, **kwargs):
orig = list(args)
if append_arg:
if self.index == -1:
orig.append(self.value)
else:
orig.insert(self.index, self.value)
return Chain(prop(*orig, **kwargs), index=self.index)
return fn
else:
return Chain(prop, index=self.index)
file = Chain(__file__).open('r').readlines().value
result = Chain(range(0, 100), index=-1).map(lambda x: x * x).reduce(lambda x, y: x + y).value