Calling a function dynamically

P

Paradox

I would like to call a function whose name I supply at runtime.
Something like this but it didn't work

functionName = 'run'
instance = ClassDef()
args = [1, 2]

#want the dynamic equivalant of
#instance.run(*args)

#This didn't work cause there was no __call__ attribute. Why?
value = instance.__call__[functionName](*args)




Thanks Joey
 
A

anton muhin

Paradox said:
I would like to call a function whose name I supply at runtime.
Something like this but it didn't work

functionName = 'run'
instance = ClassDef()
args = [1, 2]

#want the dynamic equivalant of
#instance.run(*args)

#This didn't work cause there was no __call__ attribute. Why?
value = instance.__call__[functionName](*args)




Thanks Joey

This should work:
getattr(instance, functionName)(*args)

regards,
anton.
 
E

Eric Brunel

Paradox said:
I would like to call a function whose name I supply at runtime.
Something like this but it didn't work

functionName = 'run'
instance = ClassDef()
args = [1, 2]

#want the dynamic equivalant of
#instance.run(*args)

#This didn't work cause there was no __call__ attribute. Why?
value = instance.__call__[functionName](*args)

The "function" is in fact a method on the instance, that is handled like a
regular attribute. So using getattr should do what you want:

value = getattr(instance, functionName)(*args)

__call__ is for a completely different purpose, which is to define instances
that behave like functions:
.... def __call__(self):
.... print 'spam'
....spam


HTH
 
P

Peter Otten

Paradox said:
I would like to call a function whose name I supply at runtime.
Something like this but it didn't work

functionName = 'run'
instance = ClassDef()
args = [1, 2]

#want the dynamic equivalant of
#instance.run(*args)

#This didn't work cause there was no __call__ attribute. Why?
value = instance.__call__[functionName](*args)

The __call__() method is implicitly invoked when you write

value = instance(some, args)

Here's a way to abuse the [] operator (implemented by __getitem__()) to
dynamically select a method:
.... def __getitem__(self, name):
.... return getattr(self, name)
.... def run(self, *args):
.... print "run%s" % (args,)
....
<bound method Test.run of <__main__.Test instance at 0x40295b0c>>

"bound method" means that both instance and method are stored, so that
for the actual call you need not provide an explicit self parameter:
t["run"]("alpha", "beta", "gamma")
run('alpha', 'beta', 'gamma')


Peter
 
D

Dave Benjamin

Paradox said:
I would like to call a function whose name I supply at runtime.
[snip]

Here's a way to abuse the [] operator (implemented by __getitem__()) to
dynamically select a method...
t["run"]("alpha", "beta", "gamma")
run('alpha', 'beta', 'gamma')

I wouldn't necessarily consider this abuse. This behavior (where
square-bracket- and dot-syntax are functionally equivalent) is the normal
behavior of JavaScript, and it makes dynamic lookup of method names a snap.
Python is more flexible in giving you the option to have separate namespaces
for items and attributes, but if it makes more sense for an object to merge
the two, I see nothing wrong with it.
 
P

Paradox

Thanks to all. The getattr was exactly what I need and the __getitem__
override is a nice touch.


Dave Benjamin said:
Paradox said:
I would like to call a function whose name I supply at runtime.
[snip]

Here's a way to abuse the [] operator (implemented by __getitem__()) to
dynamically select a method...
t["run"]("alpha", "beta", "gamma")
run('alpha', 'beta', 'gamma')

I wouldn't necessarily consider this abuse. This behavior (where
square-bracket- and dot-syntax are functionally equivalent) is the normal
behavior of JavaScript, and it makes dynamic lookup of method names a snap.
Python is more flexible in giving you the option to have separate namespaces
for items and attributes, but if it makes more sense for an object to merge
the two, I see nothing wrong with it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,175
Messages
2,570,942
Members
47,490
Latest member
Finplus

Latest Threads

Top