参数Parser Python条件要求

问题描述 投票:4回答:3

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

  1. --show,接受一个字符串参数
  2. --list,不论证
  3. --add,接受一个字符串参数
  4. --number,接受一个int参数
  5. --email,接受一个字符串参数

我需要的是:

prog [--show xyz | --list | --add xyz --number 123 --email [email protected] ]

我尝试使用subparsers实现它,如下所示:

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)

问题是我不想通过命令行提供我想要使用的subparser的编号/名称。

E.g:

prog.py 1 --list prog.py 2 --add xyz --number 1234 --email [email protected]

我试图使它与mutual_exclusive_group一起工作,但不能。这种用法有办法吗?

python argparse
3个回答
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

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
投票

我通常更喜欢click库这类东西。您的示例(在命令前没有--)可以像下面这样完成:

Code:

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))

Test Code:

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

Test Results:

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.
© www.soinside.com 2019 - 2024. All rights reserved.