gpt4 book ai didi

具有常用选项的 Python 多命令 CLI

转载 作者:行者123 更新时间:2023-12-01 00:15:03 28 4
gpt4 key购买 nike

我正在为我的 Python 应用程序添加 CLI。 CLI 应允许一次运行多个命令。命令应该有公共(public)选项和个人选项。

示例:

$ python mycliapp.py --common-option1 value1 --common-option2 value2 cmd1 --cmd1-option cmd2 --cmd2-option somevalue cmd3

该示例有两个所有命令都使用的通用选项,并且每个命令可以有或没有仅该命令使用的选项。

我考虑过Python Click。它具有丰富的功能,但它不允许(至少我没有发现)在没有一些主命令的情况下使用常用选项。

使用 Click 时,上述示例将如下所示:

$ python mycliapp.py maincmd --common-option1 value1 --common-option2 value2 cmd1 --cmd1-option cmd2 --cmd2-option somevalue cmd3

此外,还考虑了 Python Argparse。看起来它可以满足我的需要,并且我已经成功编写了一个代码,该代码可以使用常见选项和单个命令,但无法使用多个命令。本页Python argparse - Add argument to multiple subparsers有很好的例子,但似乎 command2 应该是 command1 的子命令。它有点不同,因为我需要可以按任何顺序执行命令。

最佳答案

Click绝对支持这种语法。一个简单的例子如下:

import click


@click.group(chain=True)
@click.option('--common-option1')
@click.option('--common-option2')
def main(common_option1, common_option2):
pass


@main.command()
@click.option('--cmd1-option', is_flag=True)
def cmd1(cmd1_option):
pass


@main.command()
@click.option('--cmd2-option')
def cmd2(cmd2_option):
pass


@main.command()
def cmd3():
pass


if __name__ == '__main__':
main()

假设上面的内容在mycliapp.py中,我们会看到常见的帮助输出:

$ python example.py --help
Usage: example.py [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...

Options:
--common-option1 TEXT
--common-option2 TEXT
--help Show this message and exit.

Commands:
cmd1
cmd2
cmd3

对于cmd1:

$ python mycliapp.py cmd1 --help
Usage: mycliapp.py cmd1 [OPTIONS]

Options:
--cmd1-option
--help Show this message and exit.

对于cmd2:

$ python mycliapp.py cmd2 --help
Usage: mycliapp.py cmd2 [OPTIONS]

Options:
--cmd2-option TEXT
--help Show this message and exit.

等等

这样我们就可以从您的问题运行命令行:

python mycliapp.py --common-option1 value1 --common-option2 value2 \
cmd1 --cmd1-option \
cmd2 --cmd2-option somevalue \
cmd3
<小时/>

更新1

这是一个使用建议的回调模型实现管道的示例 in the documentation :

import click


@click.group(chain=True)
@click.option('--common-option1')
@click.option('--common-option2')
@click.pass_context
def main(ctx, common_option1, common_option2):
ctx.obj = {
'common_option1': common_option1,
'common_option2': common_option2,
}


@main.resultcallback()
def process_pipeline(processors, common_option1, common_option2):
print('common_option1 is', common_option1)
for func in processors:
res = func()
if not res:
raise click.ClickException('Failed processing!')


@main.command()
@click.option('--cmd1-option', is_flag=True)
def cmd1(cmd1_option):
def process():
print('This is cmd1')
return cmd1_option

return process


@main.command()
@click.option('--cmd2-option')
def cmd2(cmd2_option):
def process():
print('This is cmd2')
return cmd2_option != 'fail'

return process


@main.command()
@click.pass_context
def cmd3(ctx):
def process():
print('This is cmd3 (common option 1 is: {common_option1}'.format(**ctx.obj))
return True

return process


if __name__ == '__main__':
main()

每个命令都会返回一个 bool 值,指示它是否成功。失败的命令将中止管道处理。例如,这里 cmd1 失败,因此 cmd2 永远不会执行:

$ python mycliapp.py cmd1 cmd2
This is cmd1
Error: Failed processing!

但是如果我们让 cmd1 满意,它就会起作用:

$ python mycliapp.py cmd1 --cmd1-option cmd2
This is cmd1
This is cmd2

同样,比较一下:

$ python mycliapp.py cmd1 --cmd1-option cmd2 --cmd2-option fail cmd3
This is cmd1
This is cmd2
Error: Failed processing!

这样:

$ python mycliapp.py cmd1 --cmd1-option cmd2  cmd3
This is cmd1
This is cmd2
This is cmd3

当然,您不需要按顺序调用:

$ python mycliapp.py cmd2 cmd1 --cmd1-option
This is cmd2
This is cmd1

关于具有常用选项的 Python 多命令 CLI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59391084/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com