1

My intention is to do this:

config = {"methods": ["function1(params1)", "function2(params2)"] }

This I read from a json file. So to use it, I need to pass it to another function as follows:

for method in config[methods]:
    foo(global()[method])

I know this wont work as the globals only converts the function name from a string to function but i need this to work for functions with parameters as well.

Also I have thought of this:

config = {"methods": [("function1", params1) , ("function2", params2)] }
for method in config[methods]:
    foo(global()[method[0]](method[1]))

This will work but I might have some functions for which I wouldn't require parameters. I don't want to have a condition check for whether the second entry in the tuple exists.

Is there any other way around this? I am open to change in the entire approach including the input format. Please do suggest.

5
  • Where is the JSON data coming from? Can you change how it is formatted? Can users change the JSON data at all? Because if they can you have a security problem, a huge one. Commented May 22, 2014 at 7:11
  • If you really want to read a list of Python function signatures, and then use them as functions... why not just import a Python module? Commented May 22, 2014 at 7:16
  • @ire_and_curses : It is a part of a config file and I have other parameters in the dictionary. I have only mentioned this part in the question. Commented May 22, 2014 at 7:18
  • @MartijnPieters: It is a test suite. It is intended for user input. Security is not an issue Commented May 22, 2014 at 7:19
  • 2
    @Kevin: Then separate function name and arguments. Use a mapping of known functions to look the functions up, not globals(). Commented May 22, 2014 at 7:23

2 Answers 2

2

Here is a simplified example that works with any number of parameters:

from re import findall

def a(*args):
    for i in args:
        print i

config = {"methods": ["a('hello')", "a('hello','bye')", "a()"]}

for i in config['methods']:
    x,y = findall(r'(.*?)\((.*?)\)', i)[0]
    y = [i.strip() for i in y.split(',')]
    globals()[x](*y)


[OUTPUT]
'hello'
'hello'
'bye'

DEMO

Sign up to request clarification or add additional context in comments.

2 Comments

@Kevin, Glad you like it. Racked my brains over this one for a good half-hour
You understood my question perfectly. Thank you.. :)
0

Here's a slight modification of @sshashank124 answer, which is simpler because it accepts the data differently. I think using 'f(arg1, arg2)' is not so intuitive, and gets very repetitive. Instead, I make it to dictionary pointing to a list of lists, each one represents an execution and only contains the arguments, thusly:

config = { "methods": {"a": [ ["hello"], ["hello","bye"], [] ]} }

means:

a("hello")
a("hello", "bye")
a()

I'm not sure it's any better than Shank's version, but I think it's easier to understand:

def a(*args):
    for i in args:
        print i

config = { "methods": {"a": [ ["hello"], ['hello','bye'], [] ]} }

for f,args in config['methods'].items():
    for arg in args:
        globals()[f](*arg)

DEMO

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.