13

Python 3.2 documentationCollin Winter's functional module含有功能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的特殊语法。

+0

Python 3里有加时赛的'callable'内置关键字 - 它通常是与'取代hasattr(obj,“__call__”)'否则,上面的代码应该可以工作。 – jsbueno

+3

'callable()'被添加回3.2中的语言。 –

+0

我认为在Python 3.2中应该没问题。正如其他人指出的那样,对于Python 3.0和3.1,您需要实现'callable',但如果您对3.2感到满意,只需复制,粘贴和信用。 –

回答

6

您的compose的实现对python 3.2有效,如上面的注释中所讨论的。 您提供的库的大部分功能都有一个等效的documentation

诸如mapfilter之类的函数已经在python中实现,并且也可以简单地表示为列表解析。 Python有一个返回对象身份的函数(作为整数),但函数库的id可以表示为lambda x: x

您可能感兴趣的另一个模块是itertoolsfunctools具有partialreduce(这是类似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))