Python: pasar una función a otra función


95

Estoy resolviendo un rompecabezas usando Python y, dependiendo del rompecabezas que esté resolviendo, tendré que usar un conjunto especial de reglas. ¿Cómo puedo pasar una función a otra función en Python?

Ejemplo

def Game(listA, listB, rules):
   if rules == True:
      do...
   else:
      do...

def Rule1(v):
  if "variable_name1" in v:
      return False
  elif "variable_name2" in v:
      return False
  else:
      return True

def Rule2(v):
  if "variable_name3" and "variable_name4" in v:
      return False
  elif "variable_name4" and variable_name1 in v:
      return False
  else:
      return True

Esto es solo un pseudo código y, por lo tanto, no es específico, pero obtengo el código para compilar, pero necesito saber cómo llamar a la función Gamey si está definida correctamente, ya que las reglas se cambiarán por Rule1(v)o Rule2(v).

Respuestas:


151

Simplemente páselo como cualquier otro parámetro:

def a(x):
    return "a(%s)" % (x,)

def b(f,x):
    return f(x)

print b(a,10)

44
Las funciones son objetos de primera clase en Python. puede pasarlos, incluirlos en dictados, listas, etc. Simplemente no incluya el paréntesis después del nombre de la función. Por ejemplo, para una función llamada myfunction: myfunctionsignifica la función en sí, myfunction()significa llamar a la función y obtener su valor de retorno.
nosklo

1
¿Y si la función es un método en un objeto y usa una propiedad de ese objeto para hacer su trabajo?
CpILL

2
¿Qué pasa si las funciones que paso tienen un número variable de argumentos de entrada? ¿Debería entonces usar argumentos de palabras clave?
H. Vabri

¿Qué pasa si las dos funciones están en archivos de Python separados?
Adrian Jimenez

25

Trate la función como una variable en su programa para que pueda pasarla a otras funciones fácilmente:

def test ():
   print "test was invoked"

def invoker(func):
   func()

invoker(test)  # prints test was invoked

Si. En el ejemplo anterior, la invokerfunción necesitaría proporcionar esos argumentos al llamar a la función.
codeape

15

Para pasar tanto una función como cualquier argumento a la función:

from typing import Callable    

def looper(fn: Callable, n:int, *args, **kwargs):
    """
    Call a function `n` times

    Parameters
    ----------
    fn: Callable
        Function to be called.
    n: int
        Number of times to call `func`.
    *args
        Positional arguments to be passed to `func`.
    **kwargs
        Keyword arguments to be passed to `func`.

    Example
    -------
    >>> def foo(a:Union[float, int], b:Union[float, int]):
    ...    '''The function to pass'''
    ...    print(a+b)
    >>> looper(foo, 3, 2, b=4)
    6
    6
    6       
    """
    for i in range(n):
        fn(*args, **kwargs)

Dependiendo de lo que esté haciendo, podría tener sentido definir un decorator, o quizás usar functools.partial.


9

Simplemente páselo, así:

Game(list_a, list_b, Rule1)

y luego su función de Juego podría verse algo así (aún pseudocódigo):

def Game(listA, listB, rules=None):
    if rules:
        # do something useful
        # ...
        result = rules(variable) # this is how you can call your rule
    else:
        # do something useful without rules

9

El nombre de una función puede convertirse en un nombre de variable (y por lo tanto pasar como un argumento) eliminando los paréntesis. Un nombre de variable puede convertirse en un nombre de función añadiendo paréntesis.

En su ejemplo, equipare la variable rulesa una de sus funciones, dejando los paréntesis y la mención del argumento. Luego, en tu game()función, invoca rules( v )con el paréntesis y el vparámetro.

if puzzle == type1:
    rules = Rule1
else:
    rules = Rule2

def Game(listA, listB, rules):
    if rules( v ) == True:
        do...
    else:
        do...
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.