在 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中进行函数式编程时去掉很多括号。
编辑:我最终使用了toolz,它支持
pipe
ing。
这是@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
我想把这发挥到极致,并动态地完成这一切。
基本上,下面的 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
这是一个朋友做的一个简洁的库https://github.com/withjak/threadx