13

Python 3.2 文档引用了Collin Winter 的functional模块,其中包含函数compose

compose() 函数实现了函数组合。换句话说,它返回一个围绕外部和内部可调用对象的包装器,这样内部的返回值就会直接馈送到外部。

不幸的是,这个模块自 2006 年 7 月以来就没有更新过;我想知道是否有任何替代品。

现在,我只需要compose函数。下面的原始functional.compose定义对 Python 3 仍然有用吗?

def compose(func_1, func_2, unpack=False):
    """
    compose(func_1, func_2, unpack=False) -> function

    The function returned by compose is a composition of func_1 and func_2.
    That is, compose(func_1, func_2)(5) == func_1(func_2(5))
    """
    if not callable(func_1):
        raise TypeError("First argument to compose must be callable")
    if not callable(func_2):
        raise TypeError("Second argument to compose must be callable")

    if unpack:
        def composition(*args, **kwargs):
            return func_1(*func_2(*args, **kwargs))
    else:
        def composition(*args, **kwargs):
            return func_1(func_2(*args, **kwargs))
    return composition

这个SO question有点相关;它询问 Python 是否应该支持compose.

4

1 回答 1

6

如上面评论中所述,您的实现compose对 python 3.2 有效。您提供的库的大多数功能在文档中都有一个 python 等效项。

诸如map和之类的函数filter已经在 python 中实现,也可以简单地表示为列表推导式。Python 有一个id函数返回对象的标识(作为整数),但id库的函数可以表示为lambda x: x.

您可能会发现有趣的另一个模块是itertoolsand functoolswhich has partialand reduce(类似于foldl但参数顺序不同)。

下面是一些我在标准库中找不到的简单实现:

from functools import reduce

def flip(f):
    if not callable(f):
        raise TypeError("Cannot filp a non-callable object")
    def result(*args, **kw):
        args = list(args)
        args.reverse()
        return f(*args, **kw)
    return result

def ilast(i):
    return reduce(lambda _, x: x, i)

def iscanl(f, v, seq):
    yield v
    for a in seq:
        v = f(v, a)
        yield v

def scanl(*args, **kw):
    return list(iscanl(*args, **kw))

def foldl(*args, **kw):
    return ilast(iscanl(*args, **kw))
# Or using reduce
#def foldl(f, v, seq):
#    return reduce(f, seq, v)

def iscanr_reverse(f, v, seq):
    return iscanl(flip(f), v, seq)

def scanr(*args, **kw):
    result = list(iscanr_reverse(*args, **kw))
    result.reverse()
    return result

def foldr(*args, **kw):
    return ilast(iscanr_reverse(*args, **kw))
于 2012-02-01T07:49:21.787 回答