Python - Übergabe einer Funktion an eine andere Funktion

92

Ich löse ein Rätsel mit Python und je nachdem, welches Rätsel ich löse, muss ich ein spezielles Regelwerk verwenden. Wie kann ich eine Funktion in Python an eine andere Funktion übergeben?

Beispiel

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

Dies ist nur ein Pseudocode und daher nicht spezifisch, aber ich bekomme den Code zum Kompilieren, aber ich muss wissen, wie man die Funktion aufruft Gameund ob sie korrekt definiert ist, da Regeln für entweder Rule1(v)oder umgeschaltet werden Rule2(v).

Jchanger
quelle

Antworten:

147

Übergeben Sie es einfach wie jeden anderen Parameter:

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

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

print b(a,10)
John Millikin
quelle
43
Funktionen sind erstklassige Objekte in Python. Sie können sie weitergeben, in Diktate, Listen usw. aufnehmen. Fügen Sie nur nicht die Klammer nach dem Funktionsnamen ein. Beispiel für eine Funktion mit dem Namen myfunction: myfunctionbedeutet die Funktion selbst, myfunction()bedeutet, die Funktion aufzurufen und stattdessen ihren Rückgabewert abzurufen.
Nosklo
1
Und was ist, wenn die Funktion eine Methode für ein Objekt ist und eine Eigenschaft dieses Objekts verwendet, um seine Arbeit zu erledigen?
CpILL
2
Was ist, wenn die von mir übergebenen Funktionen eine unterschiedliche Anzahl von Eingabeargumenten haben? Soll ich dann Schlüsselwortargumente verwenden?
H. Vabri
Was ist, wenn sich die beiden Funktionen in separaten Python-Dateien befinden?
Adrian Jimenez
24

Behandeln Sie die Funktion als Variable in Ihrem Programm, damit Sie sie einfach an andere Funktionen übergeben können:

def test ():
   print "test was invoked"

def invoker(func):
   func()

invoker(test)  # prints test was invoked
Piotr Czapla
quelle
Ja. Im obigen Beispiel invokermüsste die Funktion diese Argumente dann beim Aufrufen der Funktion angeben.
Codeape
15

Zum Übergeben einer Funktion und aller Argumente an die Funktion:

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)

Je nachdem, was Sie tun, kann es sinnvoll sein, eine zu definieren decoratoroder möglicherweise zu verwenden functools.partial.

Ryanjdillon
quelle
9

Gib es einfach so weiter:

Game(list_a, list_b, Rule1)

und dann könnte Ihre Spielfunktion ungefähr so ​​aussehen (immer noch Pseudocode):

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
Ian Clelland
quelle
9

Ein Funktionsname kann durch Löschen der Klammern zu einem Variablennamen werden (und somit als Argument übergeben werden). Ein Variablenname kann durch Hinzufügen der Klammern zu einem Funktionsnamen werden.

Setzen Sie in Ihrem Beispiel die Variable ruleseiner Ihrer Funktionen gleich, wobei Sie die Klammern und die Erwähnung des Arguments weglassen. Rufen Sie dann in Ihrer game()Funktion rules( v )mit den Klammern und dem vParameter auf.

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

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