Python - передача функции в другую функцию - PullRequest
77 голосов
/ 29 августа 2009

Я решаю головоломку, используя 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).

Ответы [ 5 ]

126 голосов
/ 29 августа 2009

Просто передайте его как любой другой параметр:

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

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

print b(a,10)
18 голосов
/ 29 августа 2009

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

def test ():
   print "test was invoked"

def invoker(func):
   func()

invoker(test)  # prints test was invoked
9 голосов
/ 17 февраля 2016

Обобщенный подход

Для передачи функции и параметров в функцию (например, используя одну и ту же процедуру итерации для разных функций) рассмотрим следующий (python2.x) пример:

def test(a, b):
    '''The function to pass'''
    print a+b

def looper(func, **kwargs):
    '''A basic iteration function'''
    for i in range(5):
        # Our passed function with passed parameters
        func(*tuple(value for _, value in kwargs.iteritems()))

if __name__ == '__main__':
    # This will print `3` five times
    looper(test, a=1, b=2)

Некоторое объяснение

  • tuple( i for i in (1, 2, 3)) - генератор кортежей, создающий кортеж из элементов списка, наборов, кортежей ... в нашем случае значения из **kwargs
  • * перед tuple() распакует его содержимое, эффективно передавая их в качестве параметров переданной функции
  • _ в генераторе является просто заполнителем для key, так как мы не используем это

Для python3.x:

  • print(a+b) вместо print a+b
  • kwargs.items() вместо kwargs.iteritems()
8 голосов
/ 14 ноября 2012

Имя функции может стать именем переменной (и, следовательно, передаваться в качестве аргумента), если убрать скобки. Имя переменной может стать именем функции, если добавить скобки.

В вашем примере, приравнивайте переменную 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...
8 голосов
/ 29 августа 2009

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...