Argument Parser Python 条件要求
Argument Parser Python conditional requirement
我有一个维护联系人列表的 Python 程序,我希望它通过命令行支持以下选项:
- --show ,接受一个字符串参数
- --list ,不带参数
- --add ,接受一个字符串参数
- --number ,接受一个 int 参数
- --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)
问题是我不想通过命令行提供我想使用的子解析器的 number/name。
例如:
prog.py 1 --list
prog.py 2 --add xyz --number 1234 --email abc@xyz.com
我试图让它与 mutually_exclusive_group 一起工作,但不能。有没有办法绕过这种用法?
您真的需要在命令前加上双短划线 (--
) 吗?
如果没有,你可以这样做:
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 xyz
或 prog add 123
但你不能做 prog show xzy add 123
.
对于这类事情,我通常更喜欢 click
库。您的示例(命令前面没有 --
)可以像这样完成:
代码:
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.
您可以像这样使用 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
我有一个维护联系人列表的 Python 程序,我希望它通过命令行支持以下选项:
- --show ,接受一个字符串参数
- --list ,不带参数
- --add ,接受一个字符串参数
- --number ,接受一个 int 参数
- --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)
问题是我不想通过命令行提供我想使用的子解析器的 number/name。
例如:
prog.py 1 --list
prog.py 2 --add xyz --number 1234 --email abc@xyz.com
我试图让它与 mutually_exclusive_group 一起工作,但不能。有没有办法绕过这种用法?
您真的需要在命令前加上双短划线 (--
) 吗?
如果没有,你可以这样做:
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 xyz
或 prog add 123
但你不能做 prog show xzy add 123
.
对于这类事情,我通常更喜欢 click
库。您的示例(命令前面没有 --
)可以像这样完成:
代码:
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.
您可以像这样使用 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