Es posible pasar funciones con argumentos de otra función en Python?

Decir algo así como:

def perform(function):
    return function()

Pero las funciones se pasan tendrá argumentos como:

action1()
action2(p)
action3(p,r)
InformationsquelleAutor Joan Venge | 2009-04-29

7 Comentarios

  1. 273

    Qué quiere decir esto?

    def perform( fun, *args ):
        fun( *args )
    
    def action1( args ):
        something
    
    def action2( args ):
        something
    
    perform( action1 )
    perform( action2, p )
    perform( action3, p, r )
    • ¿Qué acerca de los parámetros con nombre? Es decir, def action1(arg1, arg2=None, arg3=None), ¿cómo podría usted pasar un argumento que va a ser asignado a arg3, por ejemplo?
    • realizar( diversión, **args ), consulte stackoverflow.com/questions/8954746/…
    • Lo que si perform y action1, action2 en diferentes archivos? @S. Lott
  2. 116

    Esto es lo que lambda es para:

    def Perform(f):
        f()
    
    Perform(lambda: Action1())
    Perform(lambda: Action2(p))
    Perform(lambda: Action3(p, r))
    • También por curiosidad, ¿puedes por favor decirme por qué lambdas no son buenas para este caso?
    • las lambdas son una de las mejores características de la buena lenguajes de programación. por desgracia, Python, la aplicación es muy limitada. en este caso, sin embargo, encajan a la perfección
    • Me parece que la limitada sintaxis es casi opaca; que son difíciles de explicar a n00bz. Sí, ellos hacen el trabajo aquí, y la confusión de las características de la sintaxis están ausentes. Este es, quizá, el único ejemplo que he visto de una expresión lambda que no es oscuro.
    • Así que usted podría recuperar el pasado función del resultado, ¿no sería mejor si Realizar() llamada «el retorno f()» en vez de llamar a f().
    • Creo que la lambda versión es bastante claro, pero curiosamente en las pruebas en que me encontré fue más lento para llamar a las funciones a través de la lambda de la fn(*args) método discutido en otra respuesta.
  3. 35

    Puede utilizar la función parcial de functools como así.

    from functools import partial
    
    def perform(f):
        f()
    
    perform(Action1)
    perform(partial(Action2, p))
    perform(partial(Action3, p, r))

    También trabaja con las palabras clave

    perform(partial(Action4, param1=p))
    • functools.partial también es más versátil si perform necesidades de la mano de más de más parámetros para f. E. g., uno podría llamar a perform(partial(Action3, p)) y perform(f) podría hacer algo como f("this is parameter r").
  4. 13

    Uso functools.parcial, no lambdas! Y ofc Realizar es un inútil función, usted puede pasar en torno a funciones directamente.

    for func in [Action1, partial(Action2, p), partial(Action3, p, r)]:
      func()

    • Depende de si desea que los argumentos para ser evaluado en la convocatoria sitio de Realizar o no.
  5. 6

    (meses después), un pequeño ejemplo real donde lambda es útil, parcial: no

    digamos que quieres diversos 1-dimensiones de secciones transversales a través de 2-dimensiones de la función,
    como segmentos a través de una hilera de colinas.

    quadf( x, f ) toma 1-d f y la llama para varios x.

    Llamar para cortes verticales en y = -1 0 1 y un corte horizontal en 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 )

    Hasta donde yo sé, partial no puede hacer esto —

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

    (Cómo agregar etiquetas numpy, parcial, lambda para esto ?)

  6. 4

    Esto se llama funciones parciales y hay al menos 3 maneras de hacer esto. Mi forma favorita es el uso de lambda, ya que evita la dependencia de un paquete adicional y es el menos detallado. Supongamos que usted tiene una función add(x, y) y desea pasar add(3, y) a alguna otra función como parámetro que la otra función que decide el valor de y.

    Uso lambda

    # generic function takes op and its argument
    def runOp(op, val):
        return op(val)
    
    # declare full function
    def add(x, y):
        return x+y
    
    # run example
    def main():
        f = lambda y: add(3, y)
        result = runOp(f, 1) # is 4

    Crear Su Propia Envoltura

    Aquí es necesario crear una función que devuelve la función parcial. Esta es, obviamente, mucho más detallado.

    # generic function takes op and its argument
    def runOp(op, val):
        return op(val)
    
    # declare full function
    def add(x, y):
        return x+y
    
    # declare partial function
    def addPartial(x):
        def _wrapper(y):
            return add(x, y)
        return _wrapper
    
    # run example
    def main():
        f = addPartial(3)
        result = runOp(f, 1) # is 4

    Uso parcial de functools

    Esto es casi idéntico a lambda se muestra arriba. Entonces, ¿por qué necesitamos esto? Hay algunas de las razones. En resumen, partial podría ser poco más rápido en algunos casos (véase su la aplicación) y que se puede utilizar para principios de unión vs lambda enlace.

    from functools import partial
    
    # generic function takes op and its argument
    def runOp(op, val):
        return op(val)
    
    # declare full function
    def add(x, y):
        return x+y
    
    # run example
    def main():
        f = partial(add, 3)
        result = runOp(f, 1) # is 4
  7. 1

    Aquí es una manera de hacerlo con un cierre:

        def generate_add_mult_func(func):
            def function_generator(x):
                return reduce(func,range(1,x))
            return function_generator
    
        def add(x,y):
            return x+y
    
        def mult(x,y):
            return x*y
    
        adding=generate_add_mult_func(add)
        multiplying=generate_add_mult_func(mult)
    
        print adding(10)
        print multiplying(10)
    • En cualquier caso, uno debe hacer algo más que pasar de una función a otra de cierre es el camino a seguir.

Dejar respuesta

Please enter your comment!
Please enter your name here