Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   dictionary that have functions with arguments (http://www.velocityreviews.com/forums/t350938-dictionary-that-have-functions-with-arguments.html)

s99999999s2003@yahoo.com 11-02-2005 04:02 AM

dictionary that have functions with arguments
 
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


Alex Martelli 11-02-2005 04:20 AM

Re: dictionary that have functions with arguments
 
<s99999999s2003@yahoo.com> wrote:

> 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

Ron Adam 11-02-2005 04:25 AM

Re: dictionary that have functions with arguments
 


s99999999s2003@yahoo.com wrote:
> 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



Mike Meyer 11-02-2005 05:50 AM

Re: dictionary that have functions with arguments
 
s99999999s2003@yahoo.com writes:
> 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
--
Mike Meyer <mwm@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

Neal Norwitz 11-02-2005 05:58 AM

Re: dictionary that have functions with arguments
 
Ron Adam wrote:
>
> 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


Leif K-Brooks 11-02-2005 07:30 AM

Re: dictionary that have functions with arguments
 
Alex Martelli wrote:
> 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?

Ron Adam 11-02-2005 07:47 AM

Re: dictionary that have functions with arguments
 


Neal Norwitz wrote:

> Ron Adam wrote:
>
>>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.

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


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





Alex Martelli 11-02-2005 03:21 PM

Re: dictionary that have functions with arguments
 
Leif K-Brooks <eurleif@ecritters.biz> wrote:

> Alex Martelli wrote:
> > 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

Tim Williams (gmail) 11-02-2005 04:39 PM

Re: dictionary that have functions with arguments
 
On 1 Nov 2005 20:02:41 -0800, s99999999s2003@yahoo.com
<s99999999s2003@yahoo.com> wrote:
> 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 :)


All times are GMT. The time now is 01:34 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.