提问人:overexchange 提问时间:7/22/2014 最后编辑:martineauoverexchange 更新时间:2/7/2022 访问量:36525
什么时候应该使用函数咖喱?
When should I use function currying?
问:
我什么时候应该以 cured 形式编写我的函数?不符合我的想法,需要纠正自己。
作为我学习链接的一部分,这就是我从函数咖喱中理解的。下面是一个示例:
def curry2(f):
"""Returns a function g such that g(x)(y) == f(x, y)
>>> from operator import add
>>> add_three = curry2(add)(3)
>>> add_three(4)
"""
def g(x):
def h(y):
return f(x, y)
return h
return g
在任何应用程序中,如果我知道参数的数量是固定的(比如 2 个参数)并且
函数名称是(说),那么我将定义函数并通过调用 直接在我的应用程序中使用它。normalise_range
def normalise_range(x, y):
normalise_range(x, y)
在任何应用程序中,如果我知道的话,参数的数量是固定的(比如 2 个参数),
但是函数名是变化的(可以是//我不知道..),
然后我将如上所示使用,它将接受所有接受两个参数的函数(固定)。normalise_range
average
def curry2(f):
我的问题:
- 我的理解正确吗?
- 如果是,我们可以考虑对可变数量的参数的函数进行咖喱吗?
答:
函数咖喱的目的是从更通用的函数中轻松获取专用函数。您可以通过在不同的时间预设一些参数并在之后保持固定来实现这一点。
它与命名无关。在 Python 中,您可以随时轻松重命名变量/函数。
例:
def simple_function(a):
def line(b=0):
def compute(x):
return [a+b * xi for xi in x]
return compute
return line
x = range(-4, 4, 1)
print('x {}'.format(list(x)))
print('constant {}'.format(simple_function(3)()(x)))
print('line {}'.format(simple_function(3)(-2)(x)))
给
x [-4, -3, -2, -1, 0, 1, 2, 3]
constant [3, 3, 3, 3, 3, 3, 3, 3]
line [11, 9, 7, 5, 3, 1, -1, -3]
现在这还不是那么令人兴奋。它只是用 type 的调用替换了类型的函数调用,这甚至可能被视为 Python 中不太优雅的风格。f(a,b,c)
f(a)(b)(c)
但它允许您执行以下操作:
line_through_zero = simple_function(0)
print('line through zero {}'.format(line_through_zero(1)(x))) # only slope and x
这给了
line through zero [-4, -3, -2, -1, 0, 1, 2, 3]
因此,currying 的优点是您可以获得具有固定参数的专用函数,并且可以使用这些函数,而不是编写更通用的形式并在每次调用时设置固定的参数。
咖喱的替代方法有:和。因此,在实践中,咖喱可能很有用,但如果你愿意,你也可以绕过它。partial
lambda
default parameters
评论
line_through_zero
咖喱至少有两个我能想到的优势:
1)它使你的代码(以及你的思维)保持枯燥。
假设你有一个这样的函数:
def call_me(context, args):
...
通过咖喱,您可以获得可以折腾的专用功能等。您不必再次重复上下文。context
2)从单个输入函数的角度思考比参数容易得多;不过,这有时是值得商榷的。n
Смотритетакже: 咖喱和部分应用有什么区别?
在许多方面,这种咖喱和参数对函数的部分应用的组合模拟了面向对象编程中我们所说的“工厂模式”。Currying 允许程序员创建专门的函数,正如其他人在这个论坛中指出的那样。例如,在下面检查这个(不优雅的)快速排序的实现:
leq = lambda x: lambda y: x <= y
gth = lambda x: lambda y: x > y
def qsort(L):
if L:
smalls = filter(gth(L[0]), L[1:])
bigs = filter(leq(L[0]), L[1:])
return qsort(smalls) + [L[0]] + qsort(bigs)
else:
return L
print(qsort([2, 4, 1, 4, 2]))
评论
curry2(f)
f(x, y)
Function Currying
partial application