Python 中有类似 Clojure 线程宏的东西吗?

问题描述 投票:0回答:3

在 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。

python functional-programming
3个回答
8
投票

这是@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
投票

我想把这发挥到极致,并动态地完成这一切。

基本上,下面的 Chain 类可让您将函数链接在一起,类似于 Clojure 的

->
->>
宏。它支持线程化到第一个和最后一个参数。

函数按以下顺序解析:

  1. 对象方法
  2. 局部定义变量
  3. 内置变量

代码:

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

0
投票

这是一个朋友做的一个简洁的库https://github.com/withjak/threadx

© www.soinside.com 2019 - 2024. All rights reserved.