我对Python很陌生,并且一直在寻找一种方法来调用一个函数,该函数的名称由一个字符串和一个变量的组合形成,当用户选择其中一个选项时,该函数会动态填充。
示例:
我使用菜单启动程序,为用户提供某些选项(选择1,2,3或4)
如果用户选择1,变量xyz将填充一个元组或列表中的字符串。
将此字符串分配给变量,我调用另一个函数,它给了我另一个选项。
如果我得到选项1,我的代码会将xyz varible附加到一个预定义的字符串中,该字符串将形成一个函数名称(下一个将被调用的字符串。)。
if int(option) == 1:
#prefixfunc will be that predefined string that will be the prefix for every function #to be called
exec('prefixfunc'+xyz'()')
#or
#eval('prefixfunc_'+xyz'()')
#for example, we have xyz as abc, then it calls function prefixfunc_abc()
它在代码中工作正常。我不认为这对用户添加不同输入的情况可能是一种责任。因为变量是通过在列表或元组中使用已定义的字符串来分配的。
我希望我已经清楚了。
为了更清楚:
def maint_car():
print('It Works!!! But did you come until here in a safe way?' )
def veh_func():
func=( "Maintenance", "Prices", "Back", "Quit" )
ord = 0
for i in func:
ord += 1
print(ord,'\b)', i)
picked = input('\nOption: ')
if int(picked) == 1:
exec('maint_'+xyz+'()')
def startprog():
abcd =( "car", "bike", "airplane", "Quit" )
global xyz
ord = 0
for i in abcd:
ord += 1
print(ord,'\b)', i)
picked = input('\nVehicle:')
if int(picked) == 1:
xyz = abcd[0]
veh_func()
elif int(picked) == 2:
xyz = abcd[1]
veh_func()
elif int(picked) == 3:
xyz = abcd[3]
veh_func()
elif int(picked) == 4:
print('\nBye.\n')
startprog()
答案 0 :(得分:8)
为此我会使用dict
将字符串名称映射到函数。
def test():
print "yay"
funcs = { "test": test }
funcs["test"]()
这提供了一种更好的方法,您可以使用in
运算符测试是否要非常轻松地执行该函数。
要回答:您的示例适用于eval
或exec
我会拒绝。如果您认为exec
是正确的答案,请查看您的解决方案,看看是否有更可维护,简单或明确的方法来实现您的目标。在这种情况下,基于某些用户输入将用户输入映射到要调用的函数。
答案 1 :(得分:3)
嗯,你可以这样做,但为什么有很多更好的方法呢?如:
funcs = {1: func1, 2: func2, 3: func3, 4: func4}
option = int(raw_input("Enter selection: "))
option in funcs and funcs[option]()
这里的优点是您不必遵循函数的任何特定命名约定。如果选项1是“添加名称”,则可以调用函数addname()
而不是func1()
。这将使您的代码更容易理解。
答案 2 :(得分:1)
如果您直接知道这些方法的名称,请按照@kindall的建议进行操作。如果不这样做,可以使用getattr()获取调用方法,而不必使用eval()进行编译/计算。
class ZZ(object):
def fooBar(self):
print(42)
def barFoo(self):
print(-42)
#now make a z
anInstance = ZZ()
#build up a dynamic string
string = 'foo' + 'Bar'
#fetch the attribute bound to string for the instance
method = getattr(anInstance, string)
#now execute the bound method/function (that's what the empty parens do)
method()
# out comes the following! Tada!
>>> 42
# we can inline a lot of this and just do things like
getattr(anInstance, 'bar' + 'Foo')()
# out comes the following! Again with the Tada...
>>> -42