文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>stackoverflow about python dynameic inovke function with it's name

stackoverflow about python dynameic inovke function with it's name

时间:2010-10-05  来源:lexus


Stack Overflow

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

up vote 3 down vote favorite  

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
python
link|flag asked Jul 28 at 0:56 Desmond
16 1
 
 
up vote
 
flag
Rock on! globals() worked! Thank you all for your help. – Desmond Jul 28 at 1:06
4
up vote
 
flag
Noooo! Listen to Alex Martelli! He WROTE python in a nutshell! Don't resort to using an ugly hack that is rarely if ever needed to do something you can do cleanly! Learn to use the language correctly! – jeremiahd Jul 28 at 1:14
 
add comment

6 Answers

oldest newest votes
up vote 5 down vote

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.

link|flag edited Jul 28 at 1:08 answered Jul 28 at 0:58 Alex Martelli
141k 5 127 373
 
 
up vote
 
flag
Desmond might be used to "php-style" function-name passing, which is putting a function name in a string and then passing that around and calling it, where it presumably get's evaled or something. shudder. – jeremiahd Jul 28 at 1:05
 
add comment
up vote 2 down vote

Don't pass the name of a function.

Pass the function.

fun = dork1
ned
= doIt(3, fun, 4, 9)
print (ned)
link|flag answered Jul 28 at 0:59 S.Lott
98k 6 84 266
 
   
 
add comment
up vote 1 down vote
var = 'dork1'
ned
= doIt(3, var, 4, 9)
print (ned)

In this example, var is a string. The doIt function "calls" its second argument (for which you pass var). Pass a function instead.

link|flag answered Jul 28 at 0:59 advait
1,424212
 
 
up vote
 
flag
What if I get dork1 from a dictionary value which is stored as a string? How do I convert it to a function "object" (I know that isn't the correct terminology here) rather than a string so I can pass it in correctly? – Desmond Jul 28 at 1:02
 
up vote
 
flag
Check out the eval() function: docs.python.org/library/functions.html#eval – advait Jul 28 at 1:03
1
up vote
 
flag
Your dict value should just be the function object: funcs = {'first': dork1, 'second': dork2'} do not check out the eval function, unless you are sure you need it. and even then, you probably still don't need it. There is almost certainly a better solution. – jeremiahd Jul 28 at 1:06
2
up vote
 
flag
@jeremiahd is right -- the one good reason for the name-to-function translation which I present is to avoid loading many, many modules in order to set up a system of callbacks (it might slow down startup for no purpose if most of the callbacks may be unneeded in a given run -- lazy loading will "spread the load" beyond just startup time, and only make you "pay for what you use", which in some systems is a good tradeoff). – Alex Martelli Jul 28 at 1:34
 
add comment
up vote 0 down vote

If you have to pass it as a string you can call it with:

globals()['dork1'](arg1,arg2,arg3)
link|flag answered Jul 28 at 1:00 GWW
1,724310
 
   
 
add comment
up vote -1 down vote

Functions are first-class objects in python. Do this:

var = dork1

If you must pass a string, such as user input, then:

globals()[var]

will look up the function object.

link|flag answered Jul 28 at 1:02 Mark Tolonen
2,18618
 
   
 
add comment
up vote 0 down vote

You probably shouldn't do this, but you can get the function using eval()

for example, to use len,

eval("len")(["list that len is called on"])
link|flag answered Jul 28 at 1:04 Bwmat
25518
 
   
 
add comment

Your Answer

draft saved community wiki

Not the answer you're looking for? Browse other questions tagged python or ask your own question.

tagged

python × 35728

asked

2 months ago

viewed

109 times

latest activity

2 months ago

Related

Passing on named variable arguments in python Using property() on classmethods Django ImageField core=False in newforms admin Python descriptor protocol analog in other languages? How do I make Windows aware of a service I have written in Python? Finding the methods an object has What is the best quick-read Python book out there? What's the best toolkit for doing 2d game programming with Python? Scaffolding in pylons Are there any static analysis tools for Python? Validate (X)HTML in Python Why does Python's iter() on a mapping return iterkeys() instead of iteritems()? Ruby “is” equivalent Is Python good for big software projects (not web based)? Why is my instance variable not in __dict__? How to escape os.system() calls in Python? Are there any “nice to program” GUI toolkits for Python? Django Templates and variable attributes. C-like structures in Python How do I sort a list of strings in Python? “The system cannot find the file specified” when invoking subprocess.Popen in python Unit tests in Python Setup django with WSGI and apache How do I add data to an existing model in Django?
question feed about | faq | blog | data | podcast | legal | advertising info | contact us | feedback always welcome ■ stackoverflow.com  ■ api/apps  ■ careers  ■ serverfault.com  ■ superuser.com  ■ meta  ■ area 51  ■ webapps revision: 2010.10.5.1
排行榜 更多 +
找茬脑洞的世界安卓版

找茬脑洞的世界安卓版

休闲益智 下载
滑板英雄跑酷2手游

滑板英雄跑酷2手游

休闲益智 下载
披萨对对看下载

披萨对对看下载

休闲益智 下载