函数组合 VS 作用于另一个函数的函数

发布于 2024-12-28 17:11:25 字数 1215 浏览 1 评论 0原文

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

假设我想创建一个函数,它接受一个记录,对其应用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)    

I have numerous reusable functions, all with the same signature (they take a record and return a float). I often need to combine functions into a new function.

Let's say I want to create a function that takes a record, applies f to it, and if the result is negative converts it to zero. I have two ways of doing that: composition and function modification. What are the pros and cons of each approach?

Composition:

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

Modification:

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

g = non_negative(f)    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

≈。彩虹 2025-01-04 17:11:25

假设 compose 在库中可用,那么我更喜欢此示例的样式。

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

在此示例中,无论采用哪种方式,负担都是微不足道的。但一般来说,如果很容易制作小的独立部分,然后将它们粘合在一起以制作复合代码,那么这是一个好方法。

Assuming compose is available in a library, then I would prefer that style for this example.

The main reason is that it separates out the concerns of clamping a value to non-negative values and feeding the result of one function to another. In the "modification" style, if you ever find yourself wanting to run non_negative on a value rather than on the result of a function, you'll end up with contortions like non_negative(lambda x: x)(value). And you need to write a separate function for every thing function you might want to compose, every single one of which contains the composition logic mixed in with the code for that function.

In this example, the burden is trivial whichever way you do it. But generally, if it's this easy to make small independent pieces that you then glue together to make your composite code, that's the good way to do it.

无戏配角 2025-01-04 17:11:25

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

唯一的考虑因素是您(以及阅读您的代码的任何人)认为哪一个最具可读性。在某些情况下,我发现无点风格最自然;这就是其中之一。

Your two examples amount to exactly the same thing, except that in one case you use a point-free style, and in the other you don't.

The only consideration is which you (and whoever reads your code) find the most readable. In certain cases, I find the point free style most natural; this is one of those cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文