Python - Passing a function into another function [duplicate]
Asked Answered
M

5

106

I am solving a puzzle using python and depending on which puzzle I am solving I will have to use a special set of rules. How can I pass a function into another function in Python?

Example

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

This is just a pseudo code and therefore not specific but I get the code to compile but I need to know how to call the function Game and whether it's correctly defined since rules will be switched for either Rule1(v) or Rule2(v).

Mathematical answered 28/8, 2009 at 21:1 Comment(0)
W
171

Just pass it in like any other parameter:

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

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

print b(a,10)
Whinny answered 28/8, 2009 at 21:4 Comment(4)
functions are first-class objects in python. you can pass them around, include them in dicts, lists, etc. Just don't include the parenthesis after the function name. Example, for a function named myfunction: myfunction means the function itself, myfunction() means to call the function and get its return value instead.Dowry
And what if the function is a method on an object and uses a property of that object to do its work?Schmaltz
What if the functions I pass have a varying number of input arguments? Should I then use keyword arguments?Cardio
What if the two functions are in separate python files?Exceed
D
29

Treat function as variable in your program so you can just pass them to other functions easily:

def test ():
   print "test was invoked"

def invoker(func):
   func()

invoker(test)  # prints test was invoked
Drink answered 28/8, 2009 at 21:6 Comment(1)
Yes. In the example above, the invoker function would then need to supply those arguments when calling the function.Tor
I
17

For passing both a function, and any arguments to the function:

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)

Depending on what you are doing, it could make sense to define a decorator, or perhaps use functools.partial.

Insensibility answered 17/2, 2016 at 20:31 Comment(0)
J
10

Just pass it in, like this:

Game(list_a, list_b, Rule1)

and then your Game function could look something like this (still 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
Jitter answered 28/8, 2009 at 21:12 Comment(0)
H
10

A function name can become a variable name (and thus be passed as an argument) by dropping the parentheses. A variable name can become a function name by adding the parentheses.

In your example, equate the variable rules to one of your functions, leaving off the parentheses and the mention of the argument. Then in your game() function, invoke rules( v ) with the parentheses and the v parameter.

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

def Game(listA, listB, rules):
    if rules( v ) == True:
        do...
    else:
        do...
Henrique answered 14/11, 2012 at 16:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.