Calling an arbitrary function with the right arguments

J

John O'Hagan

How to call a function with the right arguments without knowing in advance
which function? For example:

import random

def f1():
pass

def f2(foo):
pass

def f3(foo, bar):
pass

foo=random.choice((1,2,3))
bar=random.choice((1,2,3))

myfunc=random.choice((f1, f2, f3))

How to call myfunc with the right arguments?
I've been doing it this way:

f1.args=()
f2.args=('foo',)
f3.args=('foo', 'bar')

args=[vars() for i in myfunc.args]

myfunc(*args)

But it seems redundant to manually tag the functions with their own arguments'
names, and I don't like using vars(). Is there a nicer pattern?

Regards,

John
 
S

Steven D'Aprano

How to call a function with the right arguments without knowing in
advance which function? For example:
import random

def f1():
pass

def f2(foo):
pass

def f3(foo, bar):
pass

foo=random.choice((1,2,3))
bar=random.choice((1,2,3))

myfunc=random.choice((f1, f2, f3))

How to call myfunc with the right arguments?


If f1, f2 and f3 require different arguments, it's not sensible to expect
them to be interchangeable. The right way to do this is to re-write the
functions so they all have the same call signature (even if that is just
to ignore unnecessary arguments). Or wrap the functions (perhaps using
functools.partial) so they don't need the extra args.

f3 = lambda f=f3: f(foo, bar)
f2 = lambda f=f2: f(foo)



Either way, there's a reason you never see callback functions that accept
arbitrary arguments. They always have a standard, fixed argument list.
 
B

Bruno Desthuilliers

John O'Hagan a écrit :
How to call a function with the right arguments without knowing in advance
which function?

(snip)

For most use case I can think of, I can only second Steven and Chris -
if your functions are interchangeable then they should have a same API.

Now there's at least one use case I know where you need to dynamically
select a function then build the right arguments set for it: when
mapping urls to http request handler functions. There's a good example
in Django's url to "view" mapping system.
 
P

Peter Otten

John said:
How to call a function with the right arguments without knowing in advance
which function? For example:

import random

def f1():
pass

def f2(foo):
pass

def f3(foo, bar):
pass

foo=random.choice((1,2,3))
bar=random.choice((1,2,3))

myfunc=random.choice((f1, f2, f3))

How to call myfunc with the right arguments?
I've been doing it this way:

f1.args=()
f2.args=('foo',)
f3.args=('foo', 'bar')

args=[vars() for i in myfunc.args]

myfunc(*args)

But it seems redundant to manually tag the functions with their own
arguments' names, and I don't like using vars(). Is there a nicer pattern?


You can use inspect.getargspec() to determine the argument names:

args = [vars()[argname] for argname in inspect.getargspec(myfunc).args]
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top