Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Passing a function name as an argument in a function

Tags:

I am trying to pass the name of a function into another function as an argument but I get an error: TypeError: 'str' object is not callable. Here is a simplified example of the problem:

def doIt(a, func, y, z):     result = z     result = func(a, y, result)     return result  def dork1(arg1, arg2, arg3):     thing = (arg1 + arg2) / arg3     return thing  def dork2(arg1, arg2, arg3):     thing = arg1 + (arg2 / arg3)     return thing 

When I call doIt like so:

var = 'dork1' ned = doIt(3, var, 4, 9) print (ned) 

I get:

Traceback (most recent call last):    File "<pyshell#9>", line 1, in <module>      ned = doIt(3, var, 4, 9)    File "<pyshell#2>", line 3, in doIt      result = func(a, y, result) TypeError: 'str' object is not callable 
like image 404
Desmond Avatar asked Jul 28 '10 00:07

Desmond


2 Answers

If you want to pass the function's name, as you said and you're doing, of course you can't call it -- why would one "call a name"? It's meaningless.

If you want to call it, pass the function itself, that is, most emphatically not

var = 'dork1' 

but rather

var = dork1 

without quotes!

Edit: the OP wonders in a comment (!) how to get a function object given the function name (as a string). As it happens I just showed how to do that in a tutorial I taught at OSCON (from which I'm just back) -- get the slides from here and see page 47, "Lazy-loading callbacks":

class LazyCallable(object):   def __init__(self, name):     self.n, self.f = name, None   def __call__(self, *a, **k):     if self.f is None:       modn, funcn = self.n.rsplit('.', 1)       if modn not in sys.modules:         __import__(modn)       self.f = getattr(sys.modules[modn],                        funcn)     self.f(*a, **k) 

So you could pass LazyCallable('somemodule.dork1') and live happily ever after. If you don't need to deal with the module of course (what a weird architecture that must imply!-) it's easy to adjust this code.

like image 106
Alex Martelli Avatar answered Oct 25 '22 11:10

Alex Martelli


Don't pass the name of a function.

Pass the function.

fun = dork1 ned = doIt(3, fun, 4, 9) print (ned) 
like image 21
S.Lott Avatar answered Oct 25 '22 09:10

S.Lott