我正在尝试从配置文件生成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
我实际上要尝试的是什么吗?
答案 0 :(得分:2)
您应该使用为命令创建另一个功能的函数,此处为示例
import click
commands = ['foo', 'bar', 'baz']
@click.group()
def main():
pass
def create_func(val):
def f():
print("I am the '{}' command".format(val))
return f
for c in commands:
main.command(name=c)(create_func(c))
if __name__ == '__main__':
main()
答案 1 :(得分:1)
问题在于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
还允许您根据需要用不同的方式命名函数。