I always use partial, though I know some people find lambdas easier to read and use them. For the most part they will behave exactly the same and whichever you choose will be personal preference.
For the most part…
If you are creating callbacks in a loop, and using a loop variable as an argument for the callback, then you should use partial. lambda evaluates the variable at runtime, whereas partial evaluates when the partial function is created. An example:
def printValue(v):
print v
def lambdas():
callbacks = []
for i in range(5):
callbacks.append(lambda: printValue(i))
for cb in callbacks:
cb()
def partials():
from functools import partial
callbacks = []
for i in range(5):
callbacks.append(partial(printValue, i))
for cb in callbacks:
cb()
print 'lambdas:'
lambdas()
print 'partials:'
partials()
#
lambdas:
4
4
4
4
4
partials:
0
1
2
3
4
This isn’t just an issue in for loops. If you change the value of a variable that is referenced in a lambda function you will get an unexpected result since it will resolve that variable whenever the lambda is called, not when it was created.
I should add that you actually can get lambdas to resolve variables at creation by passing them as default arguments. I just find it more unsightly (and don’t know if there are any gotchas or side-effects with this method).
callbacks = []
for i in range(5):
callbacks.append(lambda x=i: printValue(x))
for cb in callbacks:
cb()
0
1
2
3
4
In a simple context (just making a single callback or a series of one-off calls) lambdas are fine. If you’re re-using variables - which includes any form of looping (!!) partials are better because they don’t suffer from late resolution the way lamdas do.