Skip to main content
 首页 » 编程设计

python之是否可以在 Python Click 中动态生成命令

2025年05月04日21zfyouxi

我正在尝试从配置文件生成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 还允许您根据需要以不同方式命名您的函数。