如果elif-elif-else更好的写作方式



如何改进(减少写入(这个if-else块,以便根据输入的选项运行方法?我试着在SO和其他各个领域寻找解决方案,但没有找到适合我的问题的方法。

def funcA(arg1, arg2):
...
def funcB(arg1):
...
def funcC():
...
def funcD():
...
def funcE():
...
if option == 1:
funcA(arg1, arg2)
elif option == 2:
funcB(arg1)
elif option == 3:
funcC()
elif option == 4:
funcD()
elif option == 5:
funcE()
else:
pass

如果代码不清楚,我们深表歉意。

您可以使用字典作为调度表,并使用namedtuples来存储函数&参数配对。

from collections import namedtuple
def funcA(arg1, arg2):
print(f'I am funcA and you gave me {arg1} and {arg2}')
def funcB(arg):
print(f'I am funcB and you gave me {arg}')
def funcC():
print(f'I am funcC')
def funcD():
print(f'I am funcD')
def funcE():
print(f'I am funcE')
OptionPairing = namedtuple('OptionPairing', ['f', 'args'])
dispatch = {
1: OptionPairing(funcA, [True, False]),
2: OptionPairing(funcB, [True]),
3: OptionPairing(funcC, []),
4: OptionPairing(funcD, []),
5: OptionPairing(funcE, [])
}
for i in range(1, 6):
choice = dispatch[i]
x = choice.f(*choice.args)

运行此程序,会得到以下结果:

I am funcA and you gave me True and False
I am funcB and you gave me True
I am funcC
I am funcC
I am funcE

如果您想指定要传递给函数的参数,只需以下即可:

dispatch = {
1: funcA,
2: funcB,
3: funcC,
4: funcD,
5: funcE,
}

然后这样调用你的函数:

dispatch[option](args)

确保将参数args作为列表传递,因为参数的数量是可变的。

您可以使用字典方法吗?

funcs = {
1: funcA,
2: funcB,
...
}
func = funcs.get(option)
if func is None:
return 
print(f"Running func: {func.__name__}")
func(*args, **kwargs)

正如您所说,在python中,用字典进行类似开关的结构是很常见的。然而,在你的情况下,我认为if/else看起来还可以,因为以下内容有点模糊:

option = 2
def funcA(arg1, arg2):
print("A")
def funcB(arg1):
print("B")
def funcC():
print("C")
def funcD():
print("D")
def funcE():
print("E")
func, args = {
1: (funcA, ("arg1", "arg2")),
2: (funcB, ("arg1",)),
3: (funcC, ()),
4: (funcD, ()),
5: (funcE, ()),
}.get(option, (None, (),))
if func:
func(*args)

这实际上取决于你有多少函数和参数,但我建议你坚持使用一些函数if/else-

您可以使用函数及其参数的字典:

actions = {
1: [ func1 , [arg1,arg2] ]
2: [ func2 , [arg1] ]
3: [ func3 , []]
4: [ func4 , []]
5: [ func5 , []]
}
def doAction( actions , option ):
if option in actions:
func, args = actions[option]
func(*args)

您可以使用助手函数来模仿switch/case语句,避免丑陋的重复(以及相应的维护麻烦(:

def switch(value): yield lambda *match: value in match

示例用法:

for case in switch(option):
if   case(1): funcA(arg1, arg2)
elif case(2): funcB(arg1)
elif case(3): funcC()
elif case(4): funcD()
elif case(5): funcE()

最新更新