如何制作一个函数作曲家

How to make a function composer

我正在尝试为我的大学学位制作一个四舍五入其他函数的函数。例如,我想调用 round_sqrt = round(sqrt) 当我调用 round_sqrt(5) 时,它必须显示 2 而不是 2.23606797749979。我正在尝试的是:

def rounding(funct):
    return round(funct)

但这不起作用。

编辑:函数应该只有一个参数。例如 函数的开头应该是

def rounding(func):

所以在这个函数中 funct 函数需要四舍五入。 所以当我打电话给 rounding(abs)(3.2) 时,它显示 3.

你应该检查闭包:

def rounder(func):
    def inner(*args, **kwargs):
        return round(func(*args, **kwargs))
    return inner

然后你可以使用@字符修饰函数:

@rounder
def adder(x, y):
    return x + y

print(adder(1.1, 2.2))

输出3

补充:

  1. 您可以在闭包中使用 functools.wraps,这样您就不会丢失有关原始函数的信息(例如文档字符串、函数名称)。
  2. 您可以通过谷歌搜索这些术语找到大量用于学习闭包(例如 1, 2) and decorators (e.g. 1, 2)的资源。

对于你的具体例子,你可以这样写

def round_sqrt(x):
    return round(sqrt(x))

概括了这一点;他定义了一个函数 creates round_sqrt 给你。如果该函数已经定义,您只需将其作为参数传递给 rounder:

round_sqrt = rounder(sqrt)

当然,你不想定义round_sqrt也可以不定义。 rounder(sqrt)(3.2) 可以直接调用,尽管如果您希望多次使用它而不是每次都重新定义它,那么保护 rounder 的 return 值会更有效。

否则,装饰器语法只是(使用 Alex 的示例)

的缩写
def adder(x, y):
    return x + y

adder = rounder(adder)

正如我在评论中所说,这是一个实现组合的示例。从数学上讲,组合很简单,因为数学函数总是采用单个参数并且 return 具有单个参数。因此,两个函数 fg 的组合总是可以简单地定义为

def compose(f, g):
    def h(x):   # The name doesn't matter
        return f(g(x))
    return h

然后

round_sqrt = compose(round, sqrt)

(忽略围绕实现的各种实际问题,Python 理论上甚至可以为函数提供一个 Unicode 运算符 round_sqrt = round ∘ sort。解释 为什么 这不会发生超出了这个答案的范围。)

不过,在 Python 中,函数要复杂得多。它们可以接受多个参数,可以接受任意数量的参数和任意关键字参数,虽然每个 return 在技术上都是一个值,但该值可以是一个元组,被认为是多个值或 dict.因此,您可能希望通过多种方式将 g 的 return 值传递给函数 f,而不仅仅是简单的 compose功能。

Python 本身不支持函数组合。您可以根据 . You can define a new function explicitly as per .

使用装饰器

或者您可以使用第 3 方库。例如,通过 toolz.compose:

from toolz import compose

def adder(x, y):
    return x + y

round_adder = compose(round, adder)

round_adder(1.1, 2.2)  # 3