Python - передача функції іншій функції


94

Я розгадую головоломку за допомогою python, і залежно від того, яку головоломку я вирішую, мені доведеться використовувати спеціальний набір правил. Як я можу передати функцію в іншу функцію в Python?

Приклад

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

Це просто псевдокод і, отже, не конкретний, але я отримую код для компіляції, але мені потрібно знати, як викликати функцію Gameта чи правильно вона визначена, оскільки правила будуть замінені на Rule1(v)або Rule2(v).

Відповіді:


151

Просто передайте його як будь-який інший параметр:

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

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

print b(a,10)

44
функції - це першокласні об'єкти в python. ви можете їх передавати, включати в дикти, списки тощо. Просто не включайте дужки після імені функції. Приклад, для функції з іменем myfunction: myfunctionозначає саму функцію, myfunction()означає викликати функцію та отримати натомість її повернене значення.
nosklo

1
А що, якщо функція є методом на об'єкті і використовує властивість цього об'єкта для виконання своєї роботи?
CpILL

2
Що робити, якщо передані функції мають різну кількість вхідних аргументів? Чи слід мені тоді використовувати аргументи ключових слів?
H. Vabri

Що робити, якщо ці дві функції знаходяться в окремих файлах python?
Адріан Хіменес

25

Розгляньте функцію як змінну у вашій програмі, щоб ви могли просто передати їх іншим функціям:

def test ():
   print "test was invoked"

def invoker(func):
   func()

invoker(test)  # prints test was invoked

Так. У наведеному вище прикладі invokerфункції тоді потрібно буде надати ці аргументи під час виклику функції.
codeape

15

Для передачі функції як будь-яких аргументів:

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)

Залежно від того, що ви робите, може мати сенс визначити decoratorабо, можливо, використовувати functools.partial.


9

Просто передайте його так:

Game(list_a, list_b, Rule1)

і тоді ваша функція Game може виглядати приблизно так (все ще псевдокод):

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

Ім'я функції може стати ім'ям змінної (і, таким чином, передаватися як аргумент), скидаючи дужки. Ім'я змінної може стати іменем функції, додавши дужки.

У вашому прикладі прирівняйте змінну rulesдо однієї з ваших функцій, залишивши дужки та згадування аргументу. Потім у своїй game()функції викличте rules( v )дужки та vпараметр.

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

def Game(listA, listB, rules):
    if rules( v ) == True:
        do...
    else:
        do...
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.