Python2.7 argparse only accepts optional arguments (prefixed) in mutually exclusive groups:
Python2.7 argparse只接受互斥组中的可选参数(前缀):
parser = argparse.ArgumentParser(prog='mydaemon')
action = parser.add_mutually_exclusive_group(required=True)
action.add_argument('--start', action='store_true', help='Starts %(prog)s daemon')
action.add_argument('--stop', action='store_true', help='Stops %(prog)s daemon')
action.add_argument('--restart', action='store_true', help='Restarts %(prog)s daemon')
$ mydaemon -h
美元mydaemon - h
usage: mydaemon [-h] (--start | --stop | --restart)
optional arguments:
-h, --help show this help message and exit
--start Starts mydaemon daemon
--stop Stops mydaemon daemon
--restart Restarts mydaemon daemon
Is there a way to make argparse arguments behaves like traditional unix daemon control:
有没有一种方法可以使argparse参数像传统的unix守护进程控件那样运行:
(start | stop | restart) and not (--start | --stop | --restart) ?
4 个解决方案
#1
55
For all the abilities and options in argparse
I don't think you'll ever get a "canned" usage string that looks like what you want.
对于argparse的所有功能和选项,我不认为您会得到一个“罐装”的使用字符串,它看起来像您想要的。
That said, have you looked at sub-parsers since your original post?
也就是说,从你最初的帖子开始,你看过子解析器了吗?
Here's a barebones implementation:
这是一个贫乏的实现:
import argparse
parser = argparse.ArgumentParser(prog='mydaemon')
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon')
sp_stop = sp.add_parser('stop', help='Stops %(prog)s daemon')
sp_restart = sp.add_parser('restart', help='Restarts %(prog)s daemon')
parser.parse_args()
Running this with the -h
option yields:
使用-h选项运行此操作可以得到:
usage: mydaemon [-h] {start,stop,restart} ...
positional arguments:
{start,stop,restart}
start Starts mydaemon daemon
stop Stops mydaemon daemon
restart Restarts mydaemon daemon
One of the benefits of this approach is being able to use set_defaults
for each sub-parser to hook up a function directly to the argument. I've also added a "graceful" option for stop
and restart
:
这种方法的好处之一是可以为每个子解析器使用set_defaults来将函数直接连接到参数。我还添加了一个“优雅”的停止和重新启动选项:
import argparse
def my_stop(args):
if args.gracefully:
print "Let's try to stop..."
else:
print 'Stop, now!'
parser = argparse.ArgumentParser(prog='mydaemon')
graceful = argparse.ArgumentParser(add_help=False)
graceful.add_argument('-g', '--gracefully', action='store_true', help='tries to terminate the process gracefully')
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon')
sp_stop = sp.add_parser('stop', parents=[graceful],
description='Stops the daemon if it is currently running.',
help='Stops %(prog)s daemon')
sp_restart = sp.add_parser('restart', parents=[graceful], help='Restarts %(prog)s daemon')
# Hook subparsers up to functions
sp_stop.set_defaults(func=my_stop)
# Uncomment when my_start() and
# my_restart() are implemented
#
# sp_start.set_defaults(func=my_start)
# sp_restart.set_defaults(func=my_restart)
args = parser.parse_args()
args.func(args)
Showing the "help" message for stop
:
显示停止的“帮助”信息:
$ python mydaemon.py stop -h
usage: mydaemon stop [-h] [-g]
Stops the daemon if it is currently running.
optional arguments:
-h, --help show this help message and exit
-g, --gracefully tries to terminate the process gracefully
Stopping "gracefully":
停止“优雅”:
$ python mydaemon.py stop -g
Let's try to stop...
#2
34
It sounds like you want a positional argument instead of mutually exclusive options. You can use 'choices' to restrict the possible acceptable options.
听起来你想要一个位置参数而不是相互排斥的选项。您可以使用“选择”来限制可能的可接受选项。
parser = ArgumentParser()
parser.add_argument('action', choices=('start', 'stop', 'restart'))
This produces a usage line that looks like this:
这就产生了一个这样的用法:
usage: foo.py [-h] {start,stop,restart}
#3
31
from pymotw
从pymotw
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-a', action='store_true')
group.add_argument('-b', action='store_true')
print parser.parse_args()
output:
输出:
$ python argparse_mutually_exclusive.py -h
usage: argparse_mutually_exclusive.py [-h] [-a | -b]
optional arguments:
-h, --help show this help message and exit
-a
-b
$ python argparse_mutually_exclusive.py -a
Namespace(a=True, b=False)
$ python argparse_mutually_exclusive.py -b
Namespace(a=False, b=True)
$ python argparse_mutually_exclusive.py -a -b
usage: argparse_mutually_exclusive.py [-h] [-a | -b]
argparse_mutually_exclusive.py: error: argument -b: not allowed with argument -a
version2
version2
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='commands')
# A list command
list_parser = subparsers.add_parser('list', help='List contents')
list_parser.add_argument('dirname', action='store', help='Directory to list')
# A create command
create_parser = subparsers.add_parser('create', help='Create a directory')
create_parser.add_argument('dirname', action='store', help='New directory to create')
create_parser.add_argument('--read-only', default=False, action='store_true',
help='Set permissions to prevent writing to the directory',
)
# A delete command
delete_parser = subparsers.add_parser('delete', help='Remove a directory')
delete_parser.add_argument('dirname', action='store', help='The directory to remove')
delete_parser.add_argument('--recursive', '-r', default=False, action='store_true',
help='Remove the contents of the directory, too',
)
print parser.parse_args(['list', 'a s d', ])
>>> Namespace(dirname='a s d')
print parser.parse_args(['list', 'a s d', 'create' ])
>>> error: unrecognized arguments: create
#4
11
Building on Adam's answer... if you wanted to specify a default you could always do the following so they can effectively leave it blank.
建立在亚当的回答…如果您想指定一个默认值,您可以始终执行以下操作,以便它们可以有效地将其保留为空。
import argparse
ActionHelp = """
Start = Starts the daemon (default)
Stop = Stops the daemon
Restart = Restarts the daemon
"""
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('action', nargs = '?', choices=('start', 'stop', 'restart'),
default = 'start', help = ActionHelp)
print parser.parse_args(''.split())
print
print parser.parse_args('-h'.split())
which will print:
这将打印:
Namespace(action='start')
usage: program.py [-h] [{start,stop,restart}]
postional arguments:
{start,stop,restart}
Start = Starts the daemon (default)
Stop = Stops the daemon
Restart = Restarts the daemon
optional arguments:
-h, --help show this help message and exit
#1
55
For all the abilities and options in argparse
I don't think you'll ever get a "canned" usage string that looks like what you want.
对于argparse的所有功能和选项,我不认为您会得到一个“罐装”的使用字符串,它看起来像您想要的。
That said, have you looked at sub-parsers since your original post?
也就是说,从你最初的帖子开始,你看过子解析器了吗?
Here's a barebones implementation:
这是一个贫乏的实现:
import argparse
parser = argparse.ArgumentParser(prog='mydaemon')
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon')
sp_stop = sp.add_parser('stop', help='Stops %(prog)s daemon')
sp_restart = sp.add_parser('restart', help='Restarts %(prog)s daemon')
parser.parse_args()
Running this with the -h
option yields:
使用-h选项运行此操作可以得到:
usage: mydaemon [-h] {start,stop,restart} ...
positional arguments:
{start,stop,restart}
start Starts mydaemon daemon
stop Stops mydaemon daemon
restart Restarts mydaemon daemon
One of the benefits of this approach is being able to use set_defaults
for each sub-parser to hook up a function directly to the argument. I've also added a "graceful" option for stop
and restart
:
这种方法的好处之一是可以为每个子解析器使用set_defaults来将函数直接连接到参数。我还添加了一个“优雅”的停止和重新启动选项:
import argparse
def my_stop(args):
if args.gracefully:
print "Let's try to stop..."
else:
print 'Stop, now!'
parser = argparse.ArgumentParser(prog='mydaemon')
graceful = argparse.ArgumentParser(add_help=False)
graceful.add_argument('-g', '--gracefully', action='store_true', help='tries to terminate the process gracefully')
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon')
sp_stop = sp.add_parser('stop', parents=[graceful],
description='Stops the daemon if it is currently running.',
help='Stops %(prog)s daemon')
sp_restart = sp.add_parser('restart', parents=[graceful], help='Restarts %(prog)s daemon')
# Hook subparsers up to functions
sp_stop.set_defaults(func=my_stop)
# Uncomment when my_start() and
# my_restart() are implemented
#
# sp_start.set_defaults(func=my_start)
# sp_restart.set_defaults(func=my_restart)
args = parser.parse_args()
args.func(args)
Showing the "help" message for stop
:
显示停止的“帮助”信息:
$ python mydaemon.py stop -h
usage: mydaemon stop [-h] [-g]
Stops the daemon if it is currently running.
optional arguments:
-h, --help show this help message and exit
-g, --gracefully tries to terminate the process gracefully
Stopping "gracefully":
停止“优雅”:
$ python mydaemon.py stop -g
Let's try to stop...
#2
34
It sounds like you want a positional argument instead of mutually exclusive options. You can use 'choices' to restrict the possible acceptable options.
听起来你想要一个位置参数而不是相互排斥的选项。您可以使用“选择”来限制可能的可接受选项。
parser = ArgumentParser()
parser.add_argument('action', choices=('start', 'stop', 'restart'))
This produces a usage line that looks like this:
这就产生了一个这样的用法:
usage: foo.py [-h] {start,stop,restart}
#3
31
from pymotw
从pymotw
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-a', action='store_true')
group.add_argument('-b', action='store_true')
print parser.parse_args()
output:
输出:
$ python argparse_mutually_exclusive.py -h
usage: argparse_mutually_exclusive.py [-h] [-a | -b]
optional arguments:
-h, --help show this help message and exit
-a
-b
$ python argparse_mutually_exclusive.py -a
Namespace(a=True, b=False)
$ python argparse_mutually_exclusive.py -b
Namespace(a=False, b=True)
$ python argparse_mutually_exclusive.py -a -b
usage: argparse_mutually_exclusive.py [-h] [-a | -b]
argparse_mutually_exclusive.py: error: argument -b: not allowed with argument -a
version2
version2
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='commands')
# A list command
list_parser = subparsers.add_parser('list', help='List contents')
list_parser.add_argument('dirname', action='store', help='Directory to list')
# A create command
create_parser = subparsers.add_parser('create', help='Create a directory')
create_parser.add_argument('dirname', action='store', help='New directory to create')
create_parser.add_argument('--read-only', default=False, action='store_true',
help='Set permissions to prevent writing to the directory',
)
# A delete command
delete_parser = subparsers.add_parser('delete', help='Remove a directory')
delete_parser.add_argument('dirname', action='store', help='The directory to remove')
delete_parser.add_argument('--recursive', '-r', default=False, action='store_true',
help='Remove the contents of the directory, too',
)
print parser.parse_args(['list', 'a s d', ])
>>> Namespace(dirname='a s d')
print parser.parse_args(['list', 'a s d', 'create' ])
>>> error: unrecognized arguments: create
#4
11
Building on Adam's answer... if you wanted to specify a default you could always do the following so they can effectively leave it blank.
建立在亚当的回答…如果您想指定一个默认值,您可以始终执行以下操作,以便它们可以有效地将其保留为空。
import argparse
ActionHelp = """
Start = Starts the daemon (default)
Stop = Stops the daemon
Restart = Restarts the daemon
"""
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('action', nargs = '?', choices=('start', 'stop', 'restart'),
default = 'start', help = ActionHelp)
print parser.parse_args(''.split())
print
print parser.parse_args('-h'.split())
which will print:
这将打印:
Namespace(action='start')
usage: program.py [-h] [{start,stop,restart}]
postional arguments:
{start,stop,restart}
Start = Starts the daemon (default)
Stop = Stops the daemon
Restart = Restarts the daemon
optional arguments:
-h, --help show this help message and exit