基于另一个参数向 argparse 添加参数的 Pythonic 方式 [英] Pythonic way for adding parameters to argparse based on another parameter

查看:30
本文介绍了基于另一个参数向 argparse 添加参数的 Pythonic 方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在主函数中,我有一个解析器来验证可选输入:

In the main function, I have a parser which validates optional inputs:

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--platform',required=True)
    parser.add_argument('--foo')
    parser.add_argument('--bar')
    parser.add_argument('--baz')
    parser.parse_args()

上面的代码片段是一个示例,仅当我提供 --platform--foo,--bar--baz.

The above snippet is an example which only works when I supply --platform and either --foo,--bar or --baz.

这段代码被不同的组件使用,我们称它们为ABC组件.

This code is used by different components, let's call them components A, B and C.

Component A 实际上只指定了 --foo--bar :

Component A actually only specifies --foo and --bar:

python script.py --platform A --foo first_example --bar first_example

Component B 实际上只指定了 --bar--baz :

Component B actually only specifies --bar and --baz:

python script.py --platform B --bar second_example --baz second_exmaple

Component C 实际上只指定了--baz:

Component C actually only specifies --baz:

python script.py --platform C --baz third_example

随着我引入更多提供不同参数的组件,我必须添加到解析器的参数数量会增加.以上只是一个例子,我目前正在处理 20 个左右的论点(将来可能会更多).

As I introduce more components, which provide different arguments, the number of arguments I have to add to the parser increases. The above is just an example and I am currently dealing with 20 or so arguments (will likely be more in the future).

我一直在考虑拥有一个配置文件 (.yaml),我可以在其中定义每个组件需要哪些参数:

I have been thinking about having a configuration file (.yaml) where I define which arguments each component needs:

# parameters.yaml
A:
  - foo
  - bar

B:
  - bar
  - baz

C:
  - baz

我想简化主函数以查看 --platform 参数,并根据作为参数传递的平台,读取配置并向解析器添加其他参数.

I would like to simplify the main function to look at the --platform argument and, based on which platform has been passed as argument, read the configuration and add additional arguments to the parser.

这是我尝试过的:

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--platform',required=True)
    
    # Read from .yaml file
    with open('parameters.yaml') as parameter_file:
        parameters = yaml.safe_load(parameter_file)
    
    for argument in parameters[sys.argv[sys.argv.index('--platform') + 1]]:
        parser.add_argument(
           '--' + argument
    )

    parser.parse_args()

调用函数:

python script.py --platform C --baz third_example

上述代码有效,但我正在寻找其他 Pythonic 解决方案,因为我是 Python 的初学者.一世不太喜欢必须查看 sys.argv 来确定指定了什么 --platform.这个问题有没有更好的解决方案?

the above code works but I am looking for other Pythonic solutions as I am a beginner with Python. I don't really like having to look at sys.argv to determine what --platform has been specified. Are there any better solutions to this problem?

推荐答案

使用子解析器作为子命令:

With subparsers as sub-commands:

import argparse

def run_command(parser, args):
    if args.command == 'A':
        print(args)
    elif args.command == 'B':
        print(args)
    elif args.command == 'C':
        print(args)

parser = argparse.ArgumentParser(
    prog='PROG', 
    epilog="See '<command> --help' to read about a specific sub-command."
)
subparsers = parser.add_subparsers(dest='command', help='Sub-commands')

A_parser = subparsers.add_parser('A', help='Platform A')
A_parser.add_argument("--foo")
A_parser.add_argument('--bar')
A_parser.set_defaults(func=run_command)

B_parser = subparsers.add_parser('B', help='Platform B')
B_parser.add_argument('--bar')
B_parser.add_argument('--baz')
B_parser.set_defaults(func=run_command)

C_parser = subparsers.add_parser('C', help='Platform C')
C_parser.add_argument('--baz')
C_parser.set_defaults(func=run_command)

args = parser.parse_args()
if args.command is not None:
    args.func(parser, args)
else:
    parser.print_help()

这会产生:

~ python args.py -h
usage: PROG [-h] {A,B,C} ...

positional arguments:
  {A,B,C}     Sub-commands
    A         Platform A
    B         Platform B
    C         Platform C

optional arguments:
  -h, --help  show this help message and exit

See '<command> --help' to read about a specific sub-command.

~ python args.py B -h
usage: PROG B [-h] [--bar BAR] [--baz BAZ]

optional arguments:
  -h, --help  show this help message and exit
  --bar BAR
  --baz BAZ

这篇关于基于另一个参数向 argparse 添加参数的 Pythonic 方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆