我正在使用Python 2.7的argparse包为命令行工具编写一些选项解析逻辑.该工具应接受以下参数之一:
"ON":打开一个功能.
"关":关闭一个功能.
[无参数提供]:回显函数的当前状态.
查看argparse文档让我相信我想要定义两个 - 可能是三个 - 子命令,因为这三个状态是互斥的,代表不同的概念活动.这是我目前对代码的尝试:
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
Run Code Online (Sandbox Code Playgroud)
我的印象是,如果我提供了0个参数,主解析器就会设置func=print_state,如果我提供了1个参数,主解析器将使用相应的子命令的默认值并调用func=set_state.相反,我得到0参数的以下错误:
usage: cvsSecure.py [-h] {ON,OFF} ...
cvsSecure.py: error: too few arguments
Run Code Online (Sandbox Code Playgroud)
如果我提供"OFF"或"ON",则print_state调用而不是set_state.如果我注释掉该parser.set_defaults行,set_state则被正确调用.
我是一名熟练程度的程序员,但却是Python的初学者.关于如何让这个工作的任何建议?
编辑:我正在查看子命令的另一个原因是我正在考虑将来的第四个功能:
"FORCE txtval":将函数的状态设置为txtval.
srg*_*erg 12
顶级解析器的默认值覆盖了子解析器的默认值,因此func忽略在子解析器上设置默认值,但newstate子解析器默认值的值是正确的.
我认为您不想使用子命令.当可用选项和位置参数根据选择的子命令而更改时,将使用子命令.但是,您没有其他选项或位置参数.
以下代码似乎可以满足您的需求:
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)
Run Code Online (Sandbox Code Playgroud)
请注意可选参数parser.add_argument."choices"参数指定允许的选项,同时将"nargs"设置为"?" 指定如果可用则应消耗1个参数,否则不应消耗任何参数.
编辑:如果要添加带参数的FORCE命令并为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)
Run Code Online (Sandbox Code Playgroud)