This question already has an answer here:
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?
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
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