在我课程的一个训练部分,我得到了以下问题:
编写一个函数make_multiplier(factor)
,它返回一个带参数x的函数,该函数应返回factor * x。
例如:
f=make_multiplier(10)
f(1)
10
f(2)
20
我完全不知道从哪里开始;我已经通过所有笔记进行了扫描,无法找到任何有用的东西。
有人可以给我一些提示或指出我正确的方向吗?
答案 0 :(得分:4)
这是一个返回函数的函数:
def foo():
def bar():
return 42
return bar
您可以这样称呼它:
foo()() # 42
# or
baz = foo()
baz() # 42
有你的提示。
答案 1 :(得分:3)
死简单,只需嵌套你的功能:
def make_multiplier(x):
def multiplier(y):
return x * y
return multiplier
嵌套函数使用x
的值从外围函数中自动查找未知变量(在本例中为x
),就像调用外部函数时一样。这里要记住的是函数也只是对象,你可以将它们存储在变量中,就像你可以使用其他python对象一样,并推迟调用它们。
这给出了:
>>> def make_multiplier(x):
... def multiplier(y):
... return x * y
... return multiplier
...
>>> f = make_multiplier(10)
>>> f(1)
10
>>> f(2)
20
>>> g = make_multiplier(5)
>>> g(1)
5
>>> f(3)
30
请注意g
的{{1}}如何为x
赋予不同的值,该值与x
中f
的值无关。
你也可以使用lambda; lambdas只是一个表达式的匿名函数;这就够了:
def make_multiplier(x):
return lambda y: x * y
另一种替代技术是将x
绑定到关键字参数,这意味着如果您愿意,可以覆盖它:
def make_multiplier(x):
def multiply(y, x=x):
return x * y
return multiply
或lambda版本:
def make_multiplier(x):
return lambda y, x=x: x * y
然后将一个或两个参数传递给返回的callable:
>>> f = make_multiplier(10)
>>> f(5)
50
>>> f(5, 3)
15
答案 2 :(得分:0)
除了Matt Ball或Martijn Pieters闭包方法(在这种特殊情况下这是正确的答案)之外,您还会看到另外两种形式,值得在Python中识别。
第一个是使用lambda匿名函数:
>>> f=lambda x: x*10
>>> f(1)
10
>>> f(2)
20
第二个是写一个课程:
class Multiplyby:
def __init__(self,x):
self.x=x
def __call__(self,y):
return self.x*y
fx10=Multiplyby(10)
fx5=Multiplyby(5)
for y in [1,2,3]:
print y, fx10(y), fx5(y)
打印:
1 10 5
2 20 10
3 30 15
答案 3 :(得分:0)
使用lambdas:
>>> make_multiplier = lambda n: lambda x: x * n
>>> make_multiplier(10)(5)
50
10000000次循环,最佳3:每循环0.189次使用
使用stdlib:
import functools
import operator
f = lambda n: functools.partial(operator.mul, n)
10000000循环,最佳3:每循环使用0.148次
答案 4 :(得分:0)
我不推荐这个,我只是在point-lessfree style展示可能的内容:
>>> from functools import partial
>>> from operator import mul
>>> make_multiplier = partial(partial, mul)
>>> f = make_multiplier(10)
>>> f(1)
10
>>> f(2)
20