2009-08-28 1 views
49

Я решаю головоломку с использованием python и в зависимости от того, какую головоломку я решаю, мне придется использовать специальный набор правил. Как передать функцию в другую функцию в 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).

ответ

96

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

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

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

print b(a,10) 
+30

функции являются объектами первого класса в Python. вы можете передать их, включить их в dicts, списки и т. д. Просто не включайте скобки после имени функции. Например, для функции с именем 'myfunction':' myfunction' означает сама функция, 'myfunction()' означает вызов функции и получение ее возвращаемого значения. – nosklo

+3

Мне нравятся простые примеры, они просто имеют смысл !!! – mongotop

+0

А что, если функция является методом объекта и использует свойство этого объекта для выполнения своей работы? – CpILL

13

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

def test(): 
    print "test was invoked" 

def invoker(func): 
    func() 

invoker(test) # prints test was invoked 
+0

делает это, если test() принимает аргументы? @codeape ?? – Yasasvee

+0

Да. В приведенном выше примере функция '' invoker'' должна была бы затем предоставить эти аргументы при вызове функции. – codeape

7

Просто передайте его, например:

Game(list_a, list_b, Rule1) 

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

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 
7

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

В вашем примере приравниваем переменную 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... 
6

Обобщенного подход

Для прохождения как функции, а также параметров функции (например, с использованием той же итерации подпрограммы для различных функций) рассмотрят следующий (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()