我正在尝试从配置文件生成click 命令。本质上,这种模式:
import click
@click.group()
def main():
pass
commands = ['foo', 'bar', 'baz']
for c in commands:
def _f():
print("I am the '{}' command".format(c))
_f = main.command(name=c)(_f)
if __name__ == '__main__':
main()
--help 文本看起来不错:
Usage: test_click.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
bar
baz
foo
然而,所有命令似乎都路由到生成的最后一个命令:
$ ./test_click.py foo
I am the 'baz' command
$ ./test_click.py bar
I am the 'baz' command
$ ./test_click.py baz
I am the 'baz' command
我正在尝试的真的可行吗?
请您参考如下方法:
问题在于 python 的功能范围。当您创建函数 _f 时,它使用的是 c ,它具有比函数更高的作用域。所以当你调用函数时它不会被保留。 (_f 在调用 main 时被调用)
当您调用 main 时,循环已完成,c 将始终保存循环的最后一个值 - 即 baz
解决方案是将值 c 附加到使用其自己范围的函数。
import click
@click.group()
def main():
pass
commands = ['foo', 'bar', 'baz']
def bind_function(name, c):
def func():
print("I am the '{}' command".format(c))
func.__name__ = name
return func
for c in commands:
f = bind_function('_f', c)
_f = main.command(name=c)(f)
if __name__ == '__main__':
main()
bind_function 还允许您根据需要以不同方式命名您的函数。
