问题
Let's say we have a basic function:
def basic(arg):
print arg
We need to defer the evaluation of this function in another function. I am thinking about 2 possible ways:
Using lambdas:
def another(arg): return lambda: basic(arg)
Using functools.partial
from functools import partial def another(arg): return partial(basic, arg)
Which of these approaches is preferred and why? Is there another way of doing this?
回答1:
Lambdas don't store data which is not in its argument. This could lead to strange behaviors:
def lambdas(*args):
for arg in args:
yield lambda: str(arg)
one, two, three, four = lambdas(1, 2, 3, 4)
print one(), two(), three(), four()
Expected output
1 2 3 4
Output
4 4 4 4
This happens because the lambda didn't store the arg
value and it went through all the elements of args
, so now arg
is always 4
.
The preferred way is to use functools.partial, where you are forced to store the arguments:
from functools import partial
def partials(*args):
for arg in args:
yield partial(str, arg)
one, two, three, four = partials(1, 2, 3, 4)
print one(), two(), three(), four()
Expected output
1 2 3 4
Output
1 2 3 4
回答2:
I believe this mostly comes down to personal taste, although functools.partial
is believed to be somewhat faster than an equivalent lambda
. I prefer to use functools.partial
in such situations as in my opinion it makes sense to indicate that we're dealing with a simple partial function application and not a full-blown closure.
来源:https://stackoverflow.com/questions/25821832/lambda-or-functools-partial-for-deferred-function-evaluation