我正在使用Python2.7的arg解析包为命令行工具编写一些选项解析逻辑。该工具应接受下列参数之一:
“打开”:打开一个函数。
“关闭”:关闭一个功能。
没有提供任何论据*回显函数的当前状态。
查看arg解析文档使我相信,我希望定义两个-可能是三个-子命令,因为这三个状态是相互排斥的,并且代表不同的概念活动。这是我目前对代码的尝试:
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
parser.set_defaults(func=print_state) # I think this line is wrong.
parser_on = subparsers.add_parser('ON')
parser_on.set_defaults(func=set_state, newstate='ON')
parser_off = subparsers.add_parser('OFF')
parser_off.set_defaults(func=set_state, newstate='OFF')
args = parser.parse_args()
if(args.func == set_state):
set_state(args.newstate)
elif(args.func == print_state):
print_state()
else:
args.func() # Catchall in case I add more functions later
我的印象是,如果我提供了0个参数,主解析器将设置func=print_state
,如果我提供了一个参数,主解析器将使用适当的子命令的默认值并调用func=set_state
。相反,我得到以下带有0参数的错误:
usage: cvsSecure.py [-h] {ON,OFF} ...
cvsSecure.py: error: too few arguments
如果我提供“关闭”或“开启”,print_state
获取调用而不是set_state
.如果我评论一下parser.set_defaults
线,set_state
被正确调用。
我是一个熟练的程序员,但是Python的初级程序员。有什么建议可以让我这样做吗?
发布于 2018-05-25 09:38:04
以下代码似乎可以满足你的要求:
import argparse
def print_state():
print "Print state"
def set_state(s):
print "Setting state to " + s
parser = argparse.ArgumentParser()
parser.add_argument('state', choices = ['ON', 'OFF'], nargs='?')
args = parser.parse_args()
if args.state is None:
print_state()
elif args.state in ('ON', 'OFF'):
set_state(args.state)
注意可选参数parser.add_argument
。“选择”参数指定允许的选项,而将“Nargs”设置为“?”则指定如果可用,应使用1个参数,否则不应使用任何参数。
编辑:如果要添加带参数的强制命令,并为ON和OFF命令提供单独的帮助文本,则确实需要使用子命令。不幸的是,似乎没有指定默认子命令的方法。但是,可以通过检查空参数列表并提供自己的参数来解决这个问题。
import argparse
import sys
def print_state(ignored):
print "Print state"
def set_state(s):
print "Setting state to " + s
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
on = subparsers.add_parser('ON', help = 'On help here.')
on.set_defaults(func = set_state, newstate = 'ON')
off = subparsers.add_parser('OFF', help = 'Off help here.')
off.set_defaults(func = set_state, newstate = 'OFF')
prt = subparsers.add_parser('PRINT')
prt.set_defaults(func = print_state, newstate = 'N/A')
force = subparsers.add_parser('FORCE' , help = 'Force help here.')
force.add_argument('newstate', choices = [ 'ON', 'OFF' ])
force.set_defaults(func = set_state)
if (len(sys.argv) < 2):
args = parser.parse_args(['PRINT'])
else:
args = parser.parse_args(sys.argv[1:])
args.func(args.newstate)
发布于 2018-05-25 11:06:50
这应该解释为什么将默认的newstate
两次将导致第一个值被覆盖。无论是否使用“ON”或“OFF”作为参数调用您的程序,每次set_state()
将被调用OFF
。如果你只想python cvsSecure ON
和python cvsSecure OFF
以下措施将起作用:
from __future__ import print_function
import sys
import argparse
def set_state(state):
print("set_state", state)
def do_on(args):
set_state('ON')
def do_off(args):
set_state('OFF')
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
parser_on = subparsers.add_parser('ON')
parser_on.set_defaults(func=do_on)
parser_on.add_argument('--fast', action='store_true')
parser_off = subparsers.add_parser('OFF')
parser_off.set_defaults(func=do_off)
args = parser.parse_args()
args.func(args)
第二个问题是argparse
是否将子解析器作为单个值参数处理,因此必须在调用parser.parse_args()
。可以通过添加额外的子解析器“print”并使用以下方法自动插入缺少的参数set_default_subparser
加到argparse.ArgumentParser()
from __future__ import print_function
import sys
import argparse
def set_default_subparser(self, name, args=None):
"""default subparser selection. Call after setup, just before parse_args()
name: is the name of the subparser to call by default
args: if set is the argument list handed to parse_args()
, tested with 2.7, 3.2, 3.3, 3.4
it works with 2.6 assuming argparse is installed
"""
subparser_found = False
for arg in sys.argv[1:]:
if arg in ['-h', '--help']: # global help if no subparser
break
else:
for x in self._subparsers._actions:
if not isinstance(x, argparse._SubParsersAction):
continue
for sp_name in x._name_parser_map.keys():
if sp_name in sys.argv[1:]:
subparser_found = True
if not subparser_found:
# insert default in first position, this implies no
# global options without a sub_parsers specified
if args is None:
sys.argv.insert(1, name)
else:
args.insert(0, name)
argparse.ArgumentParser.set_default_subparser = set_default_subparser
def print_state(args):
print("print_state")
def set_state(state):
print("set_state", state)
def do_on(args):
set_state('ON')
def do_off(args):
set_state('OFF')
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
parser_print = subparsers.add_parser('PRINT', help='default action')
parser_print.set_defaults(func=print_state)
parser_on = subparsers.add_parser('ON')
parser_on.set_defaults(func=do_on)
parser_on.add_argument('--fast', action='store_true')
parser_off = subparsers.add_parser('OFF')
parser_off.set_defaults(func=do_off)
parser.set_default_subparser('PRINT')
args = parser.parse_args()
args.func(args)
https://stackoverflow.com/questions/-100008576
复制相似问题