0

我有许多可重用的函数,都具有相同的签名(它们采用 arecord并返回 a float)。我经常需要将函数组合成一个新函数。

假设我想创建一个接受 a 的函数record,应用于f它,如果结果为负,则将其转换为零。我有两种方法:组合和功能修改。每种方法的优缺点是什么?

作品:

def non_negative(value):
    return max(0, value)

g = compose(non_negative, f)

# from functional module by Collin Winter
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

修改:

def non_negative(func):
    def new_func(record):
        return max(0, func(record))
    return new_func

g = non_negative(f)    
4

2 回答 2

2

假设compose在图书馆中可用,那么我更喜欢这个例子的风格。

主要原因是它将一个值限制为非负值并将一个函数的结果提供给另一个函数的问题分离出来。在“修改”风格中,如果你发现自己想要运行non_negative一个值而不是函数的结果,你最终会得到像non_negative(lambda x: x)(value). 并且您需要为您可能想要组合的每个事物函数编写一个单独的函数,其中每个函数都包含与该函数的代码混合的组合逻辑。

在这个例子中,无论你怎么做,负担都是微不足道的。但一般来说,如果制作小的独立片段如此容易,然后将它们粘合在一起以制作复合代码,那么这就是这样做的好方法。

于 2012-01-26T02:23:32.543 回答
1

您的两个示例完全相同,只是在一种情况下您使用无点样式,而在另一种情况下则不使用。

唯一的考虑是您(以及阅读您的代码的人)发现哪个最易读。在某些情况下,我发现无点风格最自然;这是其中一种情况。

于 2012-01-25T16:52:12.993 回答