使用字符串在Python中调用函数

本问题已经有最佳答案,请猛点这里访问。

几天前,我在网上搜索,发现了一篇关于python字典的有趣文章。它是关于使用字典中的键来调用一个函数。在那篇文章中,作者定义了一些函数,然后定义了一个键与函数名完全相同的字典。然后他可以从user获得一个输入参数并调用相同的方法(类似于实现case break)在那之后,我意识到同样的事情,但不知何故有所不同。我想知道如何实现它。如果我有一个函数:

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

现在如果我有一个这样的字符串:

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

是否有方法执行此查询并获得结果:JoeBrand例如,我记得我们可能给exec()语句一个字符串,它为我们做了。但是我不确定这个特殊的情况,而且我也不知道Python中的有效方法。我也很感激帮助我处理函数返回值,例如,在我的例子中如何打印函数返回的全名?


这并不能完全回答你的问题,但也许它会有所帮助:

如前所述,eval应尽可能避免。在我看来,一个更好的方法是使用字典解压。这也是非常动态的,而且不容易出错。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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


您可以使用eval():

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

但是要注意,许多人认为eval()是邪恶的。


我知道这个问题很老了,但是你可以这样做:

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

argsdict是一个参数字典,globals使用字符串调用函数,**将字典扩展为一个参数列表。比eval干净多了。唯一的麻烦是把绳子弄断了。一个(非常混乱的)解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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)