dictionary that have functions with arguments

S

s99999999s2003

hi
i have a dictionary defined as

execfunc = { 'key1' : func1 }

to call func1, i simply have to write execfunc[key1] .
but if i have several arguments to func1 , like

execfunc = { 'key1' : func1(**args) }

how can i execute func1 with variable args?
using eval or exec?

thanks
 
A

Alex Martelli

hi
i have a dictionary defined as

execfunc = { 'key1' : func1 }

to call func1, i simply have to write execfunc[key1] .

No, you ALSO have to write ( ) [[parentheses]] after that. MENTIONING a
function doesn't call it, it's the parentheses that do it.
but if i have several arguments to func1 , like

execfunc = { 'key1' : func1(**args) }

how can i execute func1 with variable args?
using eval or exec?

Too late: by having those parentheses there you've ALREADY called func1
at the time the execfunc dict was being built.

Suggestion: parenthesise differently to make tuples:

execfunc = { 'key1' : (func1, ()),
'key2' : (func2, args) }

now, something like:

f, a = execfunc[k]
f(**a)

will work for either key.


Alex
 
R

Ron Adam

hi
i have a dictionary defined as

execfunc = { 'key1' : func1 }

to call func1, i simply have to write execfunc[key1] .
but if i have several arguments to func1 , like

execfunc = { 'key1' : func1(**args) }

how can i execute func1 with variable args?
using eval or exec?

thanks

Eval or exec aren't needed. Normally you would just do...

execfunc['key1'](**args)

If your arguments are stored ahead of time with your function...

execfunc = {'key1':(func1, args)}

You could then do...

func, args = execfunc['key1']
func(**args)

Cheers,
Ron
 
M

Mike Meyer

hi
i have a dictionary defined as

execfunc = { 'key1' : func1 }

to call func1, i simply have to write execfunc[key1] .
but if i have several arguments to func1 , like

execfunc = { 'key1' : func1(**args) }

how can i execute func1 with variable args?
using eval or exec?

Whenever you think "should I use eval or exec for this", you should
*immediately* stop and think "What am I doing wrong?".

Others have suggested using a tuple to hold the function and
arguments, and pointed out the mistake in your invocation.

Whenever you're thinking about doing an evalu with a fixed string, you
can replace it with a lambda. That looks like:
execfunc = dict(key1 = lambda: func1('hello'))
def func1(x): print x ....
execfunc['key1']() hello

You can use the tuple format, and then use apply and the extended call
syntax to keep it in one line:
execfunc = dict(key1 = (func1, ('hello',)))
apply(*execfunc['key1']) hello

Note that applly is depreciated - you're supposed to use the extended
call syntax instead. This particular use case for apply can't be
handled by the extended call syntax.

Using dictionaries instead of a fixed arg is a trivial change to both
these examples.

<mike
 
N

Neal Norwitz

Ron said:
Eval or exec aren't needed. Normally you would just do...

execfunc['key1'](**args)

If your arguments are stored ahead of time with your function...

Committed revision 41366.
You could then do...

func, args = execfunc['key1']
func(**args)

Interesting that both Ron and Alex made the same mistake. Hmmm, makes
me wonder if they are two people or not...

If args is a tuple, it should be:

func(*args)

If you want the full generality and use keyword args:

func(*args, **kwargs)

kwargs would be a dictionary with string keys.

E.g.,

execfunc = {'key1':(func1, (1,), {'keyarg': 42})}

HTH,
n
 
L

Leif K-Brooks

Alex said:
execfunc = { 'key1' : (func1, ()),
'key2' : (func2, args) }

now, something like:

f, a = execfunc[k]
f(**a)

will work for either key.

Shouldn't func1's args be a dictionary, not a tuple?
 
R

Ron Adam

Neal said:
Ron said:
Eval or exec aren't needed. Normally you would just do...

execfunc['key1'](**args)

If your arguments are stored ahead of time with your function...

Committed revision 41366.

Committed revision 41366 ?

You could then do...

func, args = execfunc['key1']
func(**args)


Interesting that both Ron and Alex made the same mistake. Hmmm, makes
me wonder if they are two people or not...

If args is a tuple, it should be:

func(*args)

No mistake at all, I simply reused the name the OP used in his example.

There's no rule that says you can't name a dictionary 'args', and it
wasn't part of the posters question.

If you want the full generality and use keyword args:

func(*args, **kwargs)

I tend to prefer (*args, **kwds) myself. There are also times when I
don't want full generality. In many cases the less general your
arguments are to a function the easier it is to catch errors.

Cheers,
Ron
 
A

Alex Martelli

Leif K-Brooks said:
Alex said:
execfunc = { 'key1' : (func1, ()),
'key2' : (func2, args) }

now, something like:

f, a = execfunc[k]
f(**a)

will work for either key.

Shouldn't func1's args be a dictionary, not a tuple?

Yes, to call with ** a must be a dict (so {}, not ()).


Alex
 
T

Tim Williams (gmail)

hi
i have a dictionary defined as

execfunc = { 'key1' : func1 }

##################

def __HELLO(x=' '):
print 'HELLO',x

def __BYE(x=' '):
print 'BYE',x

def __PRINT(x=None, y=None):
print 'PRINT',x,y

cmds = { 'HELLO' : __HELLO,
'BYE' : __BYE,
'PRINT' : __PRINT,
}

a = 'HELLO JOE'
b = a.split()

if cmds.has_key(b[0]):
cmds[b[0]](b[1])
# -> HELLO JOE

cmds[b[0]]()
# -> HELLO

cmds['BYE']('TOM')
# -> BYE TOM

cmds['PRINT']( 'TOM','JOE' )
# -> PRINT TOM JOE

cmds['PRINT']
# -> *No output - No exception

#####################

Inside a class use

cmds = { 'HELLO' : self.__HELLO, # etc

def __HELLO(self, x=' '): #etc


HTH :)
 

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,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top