我有一些代码如下:
if command == 'a':
do_a(a, b, c)
elif command == 'b':
do_b(a, b, c)
elif command == 'c':
do_c(a, b, c)
如何用更优雅的东西取代这类东西?也许,就像do_ [command](a,b,c)这样的东西,被调用的函数依赖于命令?
甚至可能吗?
答案 0 :(得分:2)
您可以在dict中存储命令并在需要时查找:
In [15]: commands = {'mul': lambda x,y: x*y,
'add': lambda x,y: x+y}
In [16]: commands['mul'](3,4)
Out[16]: 12
In [17]: commands['add'](3,4)
Out[17]: 7
In [18]: command = 'add'; vars = (4,5)
In [19]: commands[command](*vars)
Out[19]: 9
你应该检查一下command
是否确实在commands
:
if command in commands:
commands[command]()
else:
# handle error
答案 1 :(得分:1)
您可以使用“反射”执行类似的操作,通过字符串名称调用函数,如下所述:
Python: call a function from string name
<强> BUT 强>
如果你对command
传递的内容没有绝对的控制权,那就不会更优雅了,它会更不易读,更容易搞砸。
你的版本很好:
明确比隐含更好。
简单比复杂更好。
如果你真的想避开elif
,我会选择评论中建议的dict
函数方法。
远离eval这样的事情。
答案 2 :(得分:1)
def do(fname):
return {'a':do_a, 'b':do_b, 'c':do_c}.get(fname)
def do_a(x,y,z): return x + y + z
def do_b(x,y,z): pass
def do_c(x,y,z): pass
用法:
do('a')(1,2,3)
6
答案 3 :(得分:0)
我正在等待其他人提供更好的解决方案,但是:
def dispatch(cmd, *args):
globals()['do_' + cmd](*args)
def do_a(a, b, c):
用法:
dispatch('a', 1, 2, 3)
显然不健壮但dispatch
可以确保该函数存在。
可能一个好方法是使用装饰器。
@command()
def do_a(a,b,c):
...
@command("do_x")
def myfunc(a, b, c):
...
您的装饰者可以维护调度查找表等。
这取决于您是否担心可能需要使用现有功能或担心名称冲突。
答案 4 :(得分:0)
这可能对你有帮助,这里的源可以是任何以函数名结尾的通用模块路径 module.funcname
因此,示例调用看起来像convertStringToFunction(module.funcname)
def import_module(name):
mod = __import__(name)
components = name.split('.')
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
def convertStringToFunction(source):
tempArr = source.rsplit('.',1)
mod = import_module(tempArr[0])
func = getattr(mod, tempArr[1])
return func