参数解析器Python条件要求

时间:2018-09-16 17:16:55

标签: python argparse

我有一个维护联系人列表的Python程序,我希望它通过命令行支持以下选项:

  1. -show ,带有字符串参数
  2. -list ,不带参数
  3. -add ,带有字符串参数
  4. -number ,带有int参数
  5. -email ,带有字符串参数

我需要的是:

prog [--show xyz | --list | --add xyz --number 123 --email abcd@xyz.com ]

我尝试使用以下解析器来实现它:

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()

subparser1 = subparsers.add_parser('1')
subparser1.add_argument('--show', type=str, help="Shows the contact based on the given name provided as argument")
subparser1.add_argument('--list', action='store_true', help= "Prints all the contacts")

subparser2 = subparsers.add_parser('2')

subparser2.add_argument('--add', type=str, help="Adds a new contact by this name",required=True)
subparser2.add_argument('--number', type=int, help="The Phone Number for the new contact",required=True)
subparser2.add_argument('--email', type=str, help="Email address for the new contact",required=True)

问题是我不想在命令行中提供要使用的子解析器的编号/名称。

例如:

  

prog.py 1-列表
  prog.py 2-添加xyz-数字1234-发送电子邮件abc@xyz.com

我试图使其与 mutually_exclusive_group 一起使用,但不能。有没有办法解决这种用法?

3 个答案:

答案 0 :(得分:5)

您真的需要在命令前加双破折号(--)吗? 如果没有,您可以这样做:

import argparse

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='command')

show_subparser = subparsers.add_parser('show')
show_subparser.add_argument('name', type=str)

list_subparser = subparsers.add_parser('list')

add_subparser = subparsers.add_parser('add')
add_subparser.add_argument('phone', type=int)

args = parser.parse_args()

# Do something with your args
print args

这将限制您使用上面定义的参数。 因为您可以做prog show xyzprog add 123,但是不能做prog show xzy add 123

答案 1 :(得分:3)

您可以这样使用add_mutually_exclusive_group方法:

from argparse import ArgumentParser

parser = ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--show', help='...', action='store_true')
group.add_argument('--list', help='...', action='store_true')
group.add_argument('--add',  type=str, help='...')

parser.add_argument("--number", type=int, required=False)
parser.add_argument("--email", type=str, required=False)

args = parser.parse_args()

if args.add:
    # proceed with args.number and args.email
else:
    # ignore args.number and args.email...

输出:

$ python test.py
usage: test.py [-h] (--show | --list | --add ADD) [--number NUMBER]
               [--email EMAIL]
test.py: error: one of the arguments --show --list --add is required

答案 2 :(得分:1)

对于这种事情,我通常更喜欢Why Response.Redirect causes System.Threading.ThreadAbortException?库。您的示例(命令前没有--)可以像这样完成:

代码:

import click

@click.group()
def cli():
    """My Cool Tool"""


@cli.command()
@click.argument('name')
def show(name):
    """Shows the contact based on the given name provided as argument"""
    click.echo('Show me some cool things about {}'.format(name))


@cli.command('list')
def list_cmd():
    """Prints all the contacts"""
    click.echo('Here are some contacts')


@cli.command()
@click.argument('name')
@click.option('--number', required=True, help='The Phone Number for the new contact')
@click.option('--email', required=True, help='Email address for the new contact')
def add(name, number, email):
    """Adds a new contact by this name"""
    click.echo('Name: {}'.format(name))
    click.echo('Number: {}'.format(number))
    click.echo('Email: {}'.format(email))

测试代码:

if __name__ == "__main__":
    commands = (
        'show a_name',
        'list',
        'add a_name --number 123 --email e@mail',
        '',
        'show --help',
        'list --help',
        'add --help',
    )

    import sys, time

    time.sleep(1)
    print('Click Version: {}'.format(click.__version__))
    print('Python Version: {}'.format(sys.version))
    for cmd in commands:
        try:
            time.sleep(0.1)
            print('-----------')
            print('> ' + cmd)
            time.sleep(0.1)
            cli(cmd.split())

        except BaseException as exc:
            if str(exc) != '0' and \
                    not isinstance(exc, (click.ClickException, SystemExit)):
                raise

测试结果:

Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> show a_name
Show me some cool things about a_name
-----------
> list
Here are some contacts
-----------
> add a_name --number 123 --email e@mail
Name: a_name
Number: 123
Email: e@mail
-----------
> 
Usage: test.py [OPTIONS] COMMAND [ARGS]...

  My Cool Tool

Options:
  --help  Show this message and exit.

Commands:
  add   Adds a new contact by this name
  list  Prints all the contacts
  show  Shows the contact based on the given name...
-----------
> show --help
Usage: test.py show [OPTIONS] NAME

  Shows the contact based on the given name provided as argument

Options:
  --help  Show this message and exit.
-----------
> list --help
Usage: test.py list [OPTIONS]

  Prints all the contacts

Options:
  --help  Show this message and exit.
-----------
> add --help
Usage: test.py add [OPTIONS] NAME

  Adds a new contact by this name

Options:
  --number TEXT  The Phone Number for the new contact  [required]
  --email TEXT   Email address for the new contact  [required]
  --help         Show this message and exit.