如何制作一个函数作曲家
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
补充:
- 您可以在闭包中使用
functools.wraps
,这样您就不会丢失有关原始函数的信息(例如文档字符串、函数名称)。
- 您可以通过谷歌搜索这些术语找到大量用于学习闭包(例如 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 具有单个参数。因此,两个函数 f
和 g
的组合总是可以简单地定义为
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
我正在尝试为我的大学学位制作一个四舍五入其他函数的函数。例如,我想调用 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
补充:
- 您可以在闭包中使用
functools.wraps
,这样您就不会丢失有关原始函数的信息(例如文档字符串、函数名称)。 - 您可以通过谷歌搜索这些术语找到大量用于学习闭包(例如 1, 2) and decorators (e.g. 1, 2)的资源。
对于你的具体例子,你可以这样写
def round_sqrt(x):
return round(sqrt(x))
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 具有单个参数。因此,两个函数 f
和 g
的组合总是可以简单地定义为
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 本身不支持函数组合。您可以根据
或者您可以使用第 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