38

Some days ago I was searching on the net and I found an interesting article about python dictionaries. It was about using the keys in the dictionary to call a function. In that article the author has defined some functions, and then a dictionary with key exactly same as the function name. Then he could get an input parameter from user and call the same method (something like implementing case break) After that I realised about the same thing but somehow different. I want to know how I can implement this. If I have a function:

def fullName( name = "noName", family = "noFamily" ):
    return name += family

And now if I have a string like this:

myString = "fullName( name = 'Joe', family = 'Brand' )"

Is there a way to execute this query and get a result: JoeBrand
For example something I remember is that we might give a string to exec() statement and it does it for us. But I’m not sure about this special case, and also I do not know the efficient way in Python. And also I will be so grateful to help me how to handle that functions return value, for example in my case how can I print the full name returned by that function?

3
  • 2
    you function is gonna return None...use + instead of += Commented Nov 9, 2010 at 9:41
  • 1
    To accomplish this, use: getattr(myString, 'fullName')(name='Joe', family='Brand') [see duplicate question linked at top of page] Commented Jan 8, 2015 at 18:29
  • [Note: getattr() is used by the top answer on the question that this post duplicates, but is not mentioned below. I thought it would be helpful to appear on this page itself, so am bending the convention against answering questions in comments.] Commented Jan 8, 2015 at 18:29

3 Answers 3

53

This does not exactly answer your question, but maybe it helps nevertheless:

As mentioned, eval should be avoided if possible. A better way imo is to use dictionary unpacking. This is also very dynamic and less error prone.

Example:

def fullName(name = "noName", family = "noFamily"):
    return name + family

functionList = {'fullName': fullName}

function = 'fullName'
parameters = {'name': 'Foo', 'family': 'Bar'}

print functionList[function](**parameters)
# prints FooBar

parameters = {'name': 'Foo'}
print functionList[function](**parameters)
# prints FoonoFamily
Sign up to request clarification or add additional context in comments.

Comments

43

You could use eval():

myString = "fullName( name = 'Joe', family = 'Brand' )"
result = eval(myString)

Beware though, eval() is considered evil by many people.

5 Comments

Thanks in advance, but does it return any value from the function in case I store it in a variable?
Yes, it does. See my updated answer.
@Framester No, that is not a better answer, it is an answer for a different case. This is asking how to call a function, with no object whatsoever. The answer you're promoting is about calling an object's method.
I think that however this is a better answer since it avoids eval(): stackoverflow.com/a/22021058/9024698. If I am not wrong, it is also the answer of @kirbyfan below (stackoverflow.com/a/16683842/9024698).
13

I know this question is rather old, but you could do something like this:

argsdict = {'name': 'Joe', 'family': 'Brand'}
globals()['fullName'](**argsdict)

argsdict is a dictionary of argument, globals calls the function using a string, and ** expands the dictionary to a parameter list. Much cleaner than eval. The only trouble lies in splitting up the string. A (very messy) solution:

example = 'fullName(name=\'Joe\',family=\'Brand\')'
# Split at left parenthesis
funcname, argsstr = example.split('(')
# Split the parameters
argsindex = argsstr.split(',')
# Create an empty dictionary
argsdict = dict()
# Remove the closing parenthesis
# Could probably be done better with re...
argsindex[-1] = argsindex[-1].replace(')', '')
for item in argsindex:
    # Separate the parameter name and value
    argname, argvalue = item.split('=')
    # Add it to the dictionary
    argsdict.update({argname: argvalue})
# Call our function
globals()[funcname](**argsdict)

2 Comments

The one and only solution. Should this code reside in a module, and that module would get reloaded after fullName's code got changed, then the changes are effective in the next call to fullName. Felix Kling's answer doesn't have this property as the function is cached in functionList, and we won't even talk about how bad the eval idea is.
to reduce the mess one could use:

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.