我正在使用Python 2.7的argparse软件包为命令行工具编写一些选项解析逻辑。该工具应接受以下参数之一:
“ON”:打开功能。
“OFF”:关闭功能。
[未提供任何参数]:回显函数的当前状态。
查看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
我的印象是,如果提供0个参数,则主解析器将设置func=print_state
;如果提供1个参数,则主解析器将使用适当的子命令的默认值,并调用func=set_state
。取而代之的是,我得到以下错误,参数为0:
usage: cvsSecure.py [-h] {ON,OFF} ...
cvsSecure.py: error: too few arguments
如果我提供“OFF”或“ON”,则会调用print_state
而不是set_state
。如果我注释掉parser.set_defaults
行,则正确调用了set_state
。
我是一名熟练的程序员,但是是Python的入门者。关于如何使它正常工作的任何建议?
编辑:我正在查看子命令的另一个原因是我正在考虑的未来的第四个功能:
“FORCE txtval”:将函数的状态设置为txtval
。
参考方案
顶级解析器的默认值将覆盖子解析器的默认值,因此将忽略在子解析器上设置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)
注意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)
单行的'if'/'for'语句是否使用Python样式好? - python我经常在这里看到某人的代码,看起来像是“单线”,这是一条单行语句,以传统的“if”语句或“for”循环的标准方式执行。我在Google周围搜索,无法真正找到可以执行的搜索类型?任何人都可以提出建议并最好举一些例子吗?例如,我可以一行执行此操作吗?example = "example" if "exam" in exam…
为什么使用'=='或'is'比较字符串有时会产生不同的结果? - python我有一个Python程序,其中将两个变量设置为'public'值。在条件表达式中,我有比较var1 is var2失败,但如果将其更改为var1 == var2,它将返回True。现在,如果我打开Python解释器并进行相同的“是”比较,则此操作成功。>>> s1 = 'public' >>…
argparse参数顺序 - python我有一点问题。我使用argparse解析我的参数,并且运行良好。要拥有args,我这样做:p_args = parser.parse_args(argv) args = dict(p_args._get_kwargs()) 但是p_args的问题是我不知道如何根据命令行中的位置来排列这些参数,因为这是命令。那么,是否有可能在命令行中将参数放在元组/列表/有序…
如何处理可能是一个值或多个值的输入参数? - python我正在使用有人编写的来自GitHub的脚本,该脚本是为命令行设计的。所有示例均显示如下内容:thisscript.py -u 'teepee' -p pword999 -d 8 我想在另一个函数中运行它,在这里我可以像这样使用它:thisscript(username='teepee', password='…
在返回'Response'(Python)中传递多个参数 - python我在Angular工作,正在使用Http请求和响应。是否可以在“响应”中发送多个参数。角度文件:this.http.get("api/agent/applicationaware").subscribe((data:any)... python文件:def get(request): ... return Response(seriali…