Argparse-如何指定默认子命令 - python

我正在使用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…