Lucas
Lucas

Reputation: 1279

How to pass a method that receives parameters as a parameter of another function in Python

I know this is valid:

def printValue():
    print 'This is the printValue() method'

def callPrintValue(methodName):
    methodName()
    print 'This is the callPrintValue() method'

but is there a way to pass a method that receives parameters as a parameter of another function?

Doing this is not possible:

def printValue(value):
    print 'This is the printValue() method. The value is %s'%(value)

def callPrintValue(methodName):
    methodName()
    print 'This is the callPrintValue() method'

This is the stack trace i get:

This is the printValue() method. The value is dsdsd
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in callPrintValue
TypeError: 'NoneType' object is not callable

Upvotes: 2

Views: 303

Answers (5)

Kulbir Saini
Kulbir Saini

Reputation: 3915

As a follow up to the answers provided already, you may want to check out the the following questions on stackoverflow for a better understanding of *args and/or **kwargs and lambda in python.

  1. What does *args and **kwargs mean?
  2. What does ** (double star) and * (star) do for python parameters?
  3. Python Lambda - why?

Upvotes: 2

senderle
senderle

Reputation: 150977

Some people find lambda ugly, but it is a useful tool in cases like this. Rather than modifying the signature of callPrintValue(), you can use lambda to quickly define a new function that binds the arguments to printValue(). Whether you really want to do this depends on many factors, and it may be that adding an *args parameter as others have suggested is preferable. Still, this is an option worth considering. The following works with no modifications to your current code:

>>> callPrintValue(lambda: printValue('"Hello, I am a value"'))
This is the printValue() method. The value is "Hello, I am a value"
This is the callPrintValue() method

Upvotes: 8

mgilson
mgilson

Reputation: 309899

You want to use tuple unpacking:

def print_value(*values):
    print values

def call_print_value(func,args=None):
    func(*args)

call_print_value(print_value,args=('this','works')) #prints ('this', 'works')

From an API point of view, I prefer to keep the arguments that are passed on as a separate keyword. (then it's a little more explicit which arguments are being used by print_value and which ones are being used by call_print_value). Also note that in python, it is customary to have function (and method) names as name_with_underscores. CamelCase is generally used for class names.

Upvotes: 3

dolaameng
dolaameng

Reputation: 1437

I guess you can do this


def callPrintValue(methodName, *args):
    methodName(*args)
    print 'This is the callPrintValue() method'

make the call


callPrintValue(printValue, "abc")

Upvotes: 4

Strigoides
Strigoides

Reputation: 4509

def printValue(value):
    print 'This is the printValue() method. The value is %s'%(value)

def callPrintValue(methodName, *args):
    methodName(*args)
    print 'This is the callPrintValue() method'

Then you can call it like so:

callPrintValue(printValue, "Value to pass to printValue")

This allows you to pass in an arbitrary number of arguments, and all of them are passed to the function that you call in callPrintValue

Upvotes: 6

Related Questions