views:

2291

answers:

5

Is it possible to pass functions with arguments to another function in Python?

Say for something like:

def Perform ( function ) :
    function

but the functions to be passed will be like:

Action1()
Action2(p)
Action3(p,r)
+11  A: 

This is what lambda is for:

def Perform(f):
    f()

Perform(lambda: Action1())
Perform(lambda: Action2(p))
Perform(lambda: Action3(p, r))
Dave
-1: lambda -- there's almost always a better way.
S.Lott
Also out of curiosity, can you please tell me why lambdas are not good for this case?
Joan Venge
lambdas are one of the best features of good programming languages. unfortunately, Python's implementation is severely limited. in this case, however, they fit perfectly
Javier
I find that the limited syntax is nearly opaque; they're hard to explain to n00bz. Yes, they do work here, and the confusing features of the syntax are absent. This is -- perhaps -- the only example I've seen of a lambda that's not obscure.
S.Lott
So that you could retrieve the passed function's result, wouldn't it be better if Perform() called "return f()" rather than just calling f().
mhawke
+12  A: 

Do you mean this?

def perform( fun, *args ):
    fun( *args )

def action1( args ):
    something

def action2( args ):
    something

perform( action1 )
perform( action2, p )
perform( action3, p, r )
S.Lott
Thanks, that would work.
Joan Venge
+7  A: 
THC4k
It depends on whether you want the arguments to be evaluated at the call site of Perform or not.
Dave
+4  A: 

You can use the partial function from functools like so.

from functools import partial

def perform(f):
    f()

perform(Action1)
perform(partial(Action2, p))
perform(partial(Action3, p, r))

Also works with keywords

perform(partial(Action4, param1=p))
null
A: 

(months later) a tiny real example where lambda is useful, partial not:
say you want various 1-dimensional cross-sections through a 2-dimensional function, like slices through a row of hills.
quadf( x, f ) takes a 1-d f and calls it for various x.
To call it for vertical cuts at y = -1 0 1 and horizontal cuts at x = -1 0 1,

fx1 = quadf( x, lambda x: f( x, 1 ))
fx0 = quadf( x, lambda x: f( x, 0 ))
fx_1 = quadf( x, lambda x: f( x, -1 ))
fxy = parabola( y, fx_1, fx0, fx1 )

f_1y = quadf( y, lambda y: f( -1, y ))
f0y = quadf( y, lambda y: f( 0, y ))
f1y = quadf( y, lambda y: f( 1, y ))
fyx = parabola( x, f_1y, f0y, f1y )

As far as I know, partial can't do this --

quadf( y, partial( f, x=1 ))
TypeError: f() got multiple values for keyword argument 'x'

(How to add tags numpy, partial, lambda to this ?)

Denis