dictionary that have functions with arguments

Discussion in 'Python' started by s99999999s2003@yahoo.com, Nov 2, 2005.

  1. Guest

    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
    , Nov 2, 2005
    #1
    1. Advertising

  2. <> 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
    Alex Martelli, Nov 2, 2005
    #2
    1. Advertising

  3. Ron Adam Guest

    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
    Ron Adam, Nov 2, 2005
    #3
  4. Mike Meyer Guest

    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 <> http://www.mired.org/home/mwm/
    Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
    Mike Meyer, Nov 2, 2005
    #4
  5. Neal Norwitz Guest

    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
    Neal Norwitz, Nov 2, 2005
    #5
  6. 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?
    Leif K-Brooks, Nov 2, 2005
    #6
  7. Ron Adam Guest

    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
    Ron Adam, Nov 2, 2005
    #7
  8. Leif K-Brooks <> 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
    Alex Martelli, Nov 2, 2005
    #8
  9. On 1 Nov 2005 20:02:41 -0800,
    <> 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 :)
    Tim Williams (gmail), Nov 2, 2005
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Carl J. Van Arsdall
    Replies:
    1
    Views:
    334
    Raymond Hettinger
    Feb 16, 2006
  2. Ilias Lazaridis
    Replies:
    6
    Views:
    427
    Ilias Lazaridis
    Feb 21, 2006
  3. james_027
    Replies:
    1
    Views:
    307
    Marc 'BlackJack' Rintsch
    Aug 22, 2007
  4. py
    Replies:
    5
    Views:
    288
    Daniel DeLorme
    Mar 24, 2007
  5. oldyork90
    Replies:
    10
    Views:
    335
    Jorge
    Sep 27, 2008
Loading...

Share This Page