是否可以在 Python Click 中动态生成命令
Is it possible to dynamically generate commands in Python Click
我正在尝试从配置文件生成 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
我的尝试真的可行吗?
你应该使用为你的命令创建另一个函数的函数,这里是例子
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()
问题出在 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
还允许您根据需要为函数命名。
我正在尝试从配置文件生成 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
我的尝试真的可行吗?
你应该使用为你的命令创建另一个函数的函数,这里是例子
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()
问题出在 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
还允许您根据需要为函数命名。