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
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.
Don't pass the name of a function.
Pass the function.
fun = dork1 ned = doIt(3, fun, 4, 9) print (ned)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With