Development

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • Building a function call?

    3 answers - 1128 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    Francois De Serres wrote:
    Having a string: "dothat"
    and a tuple: (x, y)
    1. What's the best way to build a function call like: dothat(x,y)?
    Assuming dothat is def'd in the same module,
    2. is: eval("dothat(x,y)", None, (('x', 100), ('y', 200)))
    the right way to have it executed?
    If dothat is def'd in another module:
    3. what would be the right way to initialize the globals to pass to
    eval ?
    No, none of this is a good place to use eval.
    aString = "dothat"
    atuple = (x, y)
    If aString is the name of a function in the current module:
    globals()[aString](*aTuple)
    If aString is a function in another module:
    import otherModule
    vars(otherModule)[aString](*aTuple)
    and if you don't know the name of the module in advance:
    otherModule = __import__(Module)
    vars(otherModule)[aString](*aTuple)
    Better still, collect all the functions you expect to be callable in this
    way together in a dictionary and then you can be sure that you only call
    something you intended to be callable.
  • No.1 | | 1007 bytes | |

    Duncan Booth wrote:
    Francois De Serres wrote:

    >>Having a string: "dothat"
    >>and a tuple: (x, y)
    >>1. What's the best way to build a function call like: dothat(x,y)?
    >>
    >>Assuming dothat is def'd in the same module,
    >>2. is: eval("dothat(x,y)", None, (('x', 100), ('y', 200)))
    >>the right way to have it executed?
    >>
    >>If dothat is def'd in another module:
    >>3. what would be the right way to initialize the globals to pass to
    >>eval ?


    No, none of this is a good place to use eval.

    aString = "dothat"
    atuple = (x, y)

    If aString is the name of a function in the current module:

    globals()[aString](*aTuple)

    If aString is a function in another module:

    import otherModule
    vars(otherModule)[aString](*aTuple)

    Ick! Please:
    getattr(otherModule, aString)(*aTuple)
  • No.2 | | 1774 bytes | |

    Wed, 13 Jul 2005 06:16:54 -0700, Robert Kern wrote:

    Duncan Booth wrote:
    >Francois De Serres wrote:
    >

    Having a string: "dothat"
    and a tuple: (x, y)
    1. What's the best way to build a function call like: dothat(x,y)?
    [snip]
    >No, none of this is a good place to use eval.

    [snip]
    >import otherModule
    >vars(otherModule)[aString](*aTuple)


    Ick! Please:
    getattr(otherModule, aString)(*aTuple)

    , remember that functions are first class objects in Python. Instead of
    passing around the function name as a string, pass around a reference to
    the function itself. Something like this:

    def dothis(x,y):
    return x-y

    def dothat(x,y):
    return x+y

    somefunction = dothis
    somefunction(3, 2)
    =returns 1

    somefunction = dothat
    somefunction(3, 2)
    =returns 5

    allfunctions = [dothis, dothat]
    for func in allfunctions:
    print func(3, 2)
    =prints 1 then 5

    If you want to collect user-supplied strings and use them to find a
    function, you could use eval (terribly risky and unsafe), or you could do
    something like this:

    funcnames = {}
    for func in allfunctions:
    funcnames[funcname__] = func
    F = raw_input("Enter the name of a function: ")
    try:
    funcnames[F](3, 2)
    except KeyError:
    print "Function '%s' not found!" % F

    In my humble opinion, people muck about with eval, locals and globals far
    too often. It is unclear, hard to maintain, and frequently a security
    risk. These confusing, unsafe practices can usually be avoided by
    remembering that functions are first class objects just like ints, strings
    and lists.
  • No.3 | | 2658 bytes | |

    Steven D'Aprano wrote:

    Wed, 13 Jul 2005 06:16:54 -0700, Robert Kern wrote:


    >
    >>Duncan Booth wrote:

    >
    >>

    Francois De Serres wrote:

    Having a string: "dothat"
    and a tuple: (x, y)
    1. What's the best way to build a function call like: dothat(x,y)?


    >[snip]


    No, none of this is a good place to use eval.


    >[snip]


    import otherModule
    vars(otherModule)[aString](*aTuple)


    >>Ick! Please:
    >>getattr(otherModule, aString)(*aTuple)

    >
    >>

    >
    >
    >, remember that functions are first class objects in Python. Instead of
    >passing around the function name as a string, pass around a reference to
    >the function itself. Something like this:
    >
    >
    >def dothis(x,y):

    return x-y
    >
    >def dothat(x,y):

    return x+y
    >
    >somefunction = dothis
    >somefunction(3, 2)

    returns 1
    >
    >somefunction = dothat
    >somefunction(3, 2)

    returns 5
    >
    >allfunctions = [dothis, dothat]
    >for func in allfunctions:

    print func(3, 2)
    prints 1 then 5
    >
    >If you want to collect user-supplied strings and use them to find a
    >function, you could use eval (terribly risky and unsafe), or you could do
    >something like this:
    >
    >funcnames = {}
    >for func in allfunctions:

    funcnames[funcname__] = func
    >F = raw_input("Enter the name of a function: ")
    >try:

    funcnames[F](3, 2)
    >except KeyError:

    print "Function '%s' not found!" % F
    >
    >
    >In my humble opinion, people muck about with eval, locals and globals far
    >too often. It is unclear, hard to maintain, and frequently a security
    >risk. These confusing, unsafe practices can usually be avoided by
    >remembering that functions are first class objects just like ints, strings
    >and lists.
    >
    >
    >


    I'm aware of the functions being objects, but I really need to work with
    strings in that case.
    Still, I was not aware that eval() was such a 'rogue', it's not said in
    the manuals ;)
    Many thanks!
    F.

Re: Building a function call?


max 4000 letters.
Your nickname that display:
In order to stop the spam: 6 + 5 =
QUESTION ON "Development"

EMSDN.COM