如何制作函数作曲家

时间:2018-11-07 17:14:46

标签: python python-3.x python-decorators function-composition

我正在尝试使我的大学学位的职能更全面。例如,我想打电话给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

3 个答案:

答案 0 :(得分:27)

您应该查看封包:

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,以免丢失有关原始函数的信息(例如docstring,函数名)。
  2. 有很多资源可用于学习闭包(例如12)和修饰符(例如12),您可以通过谷歌搜索这些资源条款。

答案 1 :(得分:15)

对于您的特定示例,您可以编写

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

Alex's answer概括了这一点;他定义了一个为您创建 round_sqrt的函数。如果已经定义了函数,则只需将其作为参数传递给rounder

round_sqrt = rounder(sqrt)

当然,如果不需要,您不需要定义round_sqrtrounder(sqrt)(3.2)可以直接调用,尽管如果您希望多次使用rounder的返回值,而不是每次都重新定义它,则可以更安全地保护def adder(x, y): return x + y adder = rounder(adder) 的返回值。

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

f

正如我在评论中所说,这是实现合成的一个示例。从数学上讲,合成很简单,因为数学函数始终采用单个参数并返回单个参数。这样,两个函数gdef compose(f, g): def h(x): # The name doesn't matter return f(g(x)) return h 的组合始终可以简单地定义为

round_sqrt = compose(round, sqrt)

然后

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

但是,在Python中,函数要复杂得多。它们可以采用多个参数,可以接受任意数量的参数和任意关键字参数,并且在技术上每个参数都返回单个值时,该值可以是被认为是多个值或g的元组。因此,您可能希望通过多种方式将f的返回值传递给函数compose,这比简单的Timeout when reading response headers from daemon process 'horizon': /usr/share/openstack-dashboard/openstack_dashboard/wsgi.py, referer: http://192.168.1.100/horizon/project/instances/ 函数所能轻易容纳的更多。 >

答案 2 :(得分:5)

Python本身不支持功能组合。您可以按照@Alex's solution使用修饰符。您可以按照@chepner's solution显式定义一个新函数。

或者您可以使用第三方库。例如,通过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