我正在创建一个程序,其中有一个主菜单,要求用户输入一个选项并将其存储在整数option1
中,这将在字典options
中查找。然后运行相应的功能。如果函数没有参数,则以下代码可用:
options = {0 : FunctionZero, # Assign functions to the dictionary
1 : FunctionOne,
2 : FunctionTwo,
3 : FunctionThree}
options[option1]() # Call the function
如果函数有参数,上面的代码不起作用,因为()
部分假设函数没有参数,但我尝试了以下代码,它存储函数'字典中元组中的名称和参数:
options = {0 : (FunctionZero,""), # FunctionsZero, FunctionOne
1 : (FunctionOne,""), # and FunctionTwo have no parameters
2 : (FunctionTwo,""),
3 : (FunctionThree,True)} # FunctionThree has one parameter
if options[option1][1] == "": # Call the function
options[option1][0]()
else:
options[option1][0](options[option1][1])
这段代码似乎工作正常,但我想知道是否有更好的方法来做到这一点,特别是如果函数需要几个参数?在像C#这样的其他语言中,我可能会使用switch或case语句(不在Python中),并且我避免使用if...elif
语句。
答案 0 :(得分:12)
我会使用functools.partial
来指定创建字典时的参数:
from functools import partial
options = {0: FunctionZero,
1: FunctionOne,
2: FunctionTwo,
3: partial(FunctionThree, True)}
请注意,这也允许在调用函数时传递其他参数(只要字典中的所有函数在调用partial
后都缺少相同的参数):
def test(one, two, three=None, four=None):
...
def test2(one, two, three=None):
...
options = {1: partial(test, 1, three=3, four=4),
2: partial(test2, 1, three=3)}
...
options[choice](2) # pass the 'two' argument both functions still require
答案 1 :(得分:5)
不确定。在Python中,函数可以采用位置或关键字参数。对于大多数函数,参数可以以任何一种方式传递,但对于所有函数都不一定如此,因此我们需要将它们分开。位置参数是可迭代的(通常是列表或元组),关键字参数位于从字符串到值的字典中。
然后我们可以将每个函数表示为函数,位置参数和关键字参数的元组:
options = {
0: (function_zero, [], {}),
1: (function_one, [], {}),
2: (function_two, [], {}),
3: (function_three, [True], {}),
4: (function_four, [], {'kwarg': True}), # takes a keyword argument
}
然后你可以像这样打电话给他们:
func, args, kwargs = options[option1]
func(*args, **kwargs)
但是如果你总是要传递一个常量,那么有一个更好的方法:只为每个调用函数的函数创建一些无参数包装器你希望如何调用它 :
options = {
0: function_zero,
1: function_one,
2: function_two,
3: lambda: function_three(True),
4: lambda: function_four(kwarg=True),
}
然后使用您的第一种方法:
options[option1]()
详见jonrsharpe的回答,您也可以使用functools.partial
而不是lambda
。正如他所指出的,这具有能够附加一些你自己的论点的优点:
options[option1]('hello') # adds 'hello' to previously-specified arguments
如果您不需要此功能,零参数lambda
将为您提供服务。
答案 2 :(得分:3)
要添加到icktoofay's answer,如果要将参数传递给lambda,请执行以下操作:
def printDouble( number ):
print number * 2
options = {
1: lambda num: printDouble(num)
}
options[1](4) #this prints 8
通过在“:”之前添加lambda的参数,您声明lambda接收一个参数,然后在它调用的函数中使用它。
此外,如果你不想使用lambdas,你可以使用通常的方式
def printDouble( num ):
print num * 2
def printHalf( num ):
print half / 2
functionDictionary = {
'Double': printDouble,
'Half' : printHalf
}
functionDictionary['Double'](2) #This prints 4