前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python命令行库如何实现子命令共享参数?

python命令行库如何实现子命令共享参数?

作者头像
千灵域
发布2022-06-17 12:57:08
9020
发布2022-06-17 12:57:08
举报
文章被收录于专栏:challenge filter

本文参考这篇文章,比较了argparse、click的区别。尽管只用某一个也不是不可以,但我觉得我还是挺有必要进行一下对应的对比。

本文的目标: 本文计划实现一个带有子命令的命令行工具,同时带有全局级别的配置参数(比如数据文件地址等)。在这个前提下使用不同的标准来比较所提到的三个命令行库。 (原本计划把docopt也顺便学习一下的,但实在是没什么必要,这次就算了吧。)

下文将按照参考文章的目录进行组0织,我觉得它这个组织格式还挺有道理的

简要介绍

分别用三种来实现子命令下共享嵌套的情况(自己动手),均失败。 目标场景:SO上的同款问题。对于给定的子命令readwrite,父命令有一个--format参数,如何使得python main.py read --format=xxx成立。

click

click的写法依赖于decorator

  • @click.command()声明子命令
  • @click.option('--xxx',default=x,help=xxx)@click.argument('argumentName')声明参数
  • @click.group()用来实现嵌套命令
代码语言:javascript
复制
# click.group示例,执行python main.py initdb,python main.py dropdb即可,但是--debug只能在子命令下执行
import click


@click.group()
@click.option('--debug',default=False)
def cli(debug):
    click.echo(f'Debug mode is {debug}')

@click.command()
def initdb():
    click.echo('Initialized the database')

@click.command()
def dropdb():
    click.echo('Dropped the database')

cli.add_command(initdb)
cli.add_command(dropdb)


if __name__ == '__main__':
    cli()

argparse

在argparse中,子命令的实现是通过add_subparsers来实现的

代码语言:javascript
复制
import argparse


def do_command_one(arg):
    print('command1', arg)
    print(arg.cmd1_option1)
    print(arg.foo)


def do_command_two(arg):
    print('command1', arg)
    print(arg.cmd1_option1)
    print(arg.cmd1_option2)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--foo', type=str)
    subparsers = parser.add_subparsers(help='Functinos')
    parser_1 = subparsers.add_parser('model', help='This is function about model')
    parser_1.add_argument('--cmd1_option1', type=str)
    parser_1.set_defaults(func=do_command_one)
    parser_2 = subparsers.add_parser('model2', help='This is function about model')
    parser_2.add_argument('--cmd2_option1', type=str)
    parser_2.set_defaults(func=do_command_two)
    args = parser.parse_args()
    if args.func:
        args.func(args)

上面这个即为我第一次学习argparse写的实例。这个脚本文件声明了两个子命令:modelmodel2model会有一个命令行参数--cmd1_option1model2会有一个命令行参数--cmd2_option1,同时全局会有一个参数--foo

此外,使用set_defaults来设置了子命令的处理函数,以应对可能需要进行单独处理的情况。

唯一的问题是,全局参数的实现比价违背一般的习惯。python main.py --foo="test" model --cmd1_option1="test2" 才能通过,如果把--foo放在子命令之后是无法识别的。

代码语言:javascript
复制
(pythonProject)  wutianyang@TIANYANGWU-MB0  ~/PycharmProjects/commandTest  python main.py model --cmd1_option1="test" --foo="123"
usage: main.py [-h] [--foo FOO] {model,model2} ...
main.py: error: unrecognized arguments: --foo=123

除此之外,这种写法只允许运行子命令的程序才能够通过编译,这个应该是写法的问题。

实现需求

需求本身是很简单的,最关键的一点就是子命令之间要共享部分全局参数

argparse

SO上这个回答还挺不错的。执行python main.py create -p="db",从效果上来说确实是与预期一致。

代码语言:javascript
复制
import argparse
# Same main parser as usual
parser = argparse.ArgumentParser()

# Usual arguments which are applicable for the whole script / top-level args
parser.add_argument('--verbose', help='Common top-level parameter',
                    action='store_true', required=False)

# Same subparsers as usual
subparsers = parser.add_subparsers(help='Desired action to perform', dest='action')

# Usual subparsers not using common options
parser_other = subparsers.add_parser("extra-action", help='Do something without db')

# Create parent subparser. Note `add_help=False` and creation via `argparse.`
parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument('-p', help='add db parameter', required=True)

# Subparsers based on parent

parser_create = subparsers.add_parser("create", parents=[parent_parser],
                                      help='Create something')
# Add some arguments exclusively for parser_create

parser_update = subparsers.add_parser("update", parents=[parent_parser],
                                      help='Update something')
# Add some arguments exclusively for parser_update

if __name__ == '__main__':
    arg = parser.parse_args()
    print(arg)
    print(arg.action) # action
    print(arg.p) # db

click

click中也有类似的写法,不过是基于decorator改造的,也挺有意思的。SO问题。主要是我对于decorator也没什么研究,之后有时间了再进一步学习。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简要介绍
    • click
      • argparse
      • 实现需求
        • argparse
          • click
          相关产品与服务
          命令行工具
          腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档