使用子解析器时,如何使argparse参数成为可选参数? [英] How do I make an argparse argument optional when using subparsers?

查看:118
本文介绍了使用子解析器时,如何使argparse参数成为可选参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个简单的Git/Redmine胶水脚本,但是在Python argparse模块中使用可选参数时遇到了一些困难.

I'm working on a simple Git/Redmine glue script but I'm having some difficulty using optional arguments with the Python argparse module.

使用以下代码:

import argparse

class MyClass:
    def StartWork(self, issueNumber, **kwargs):
        if issueNumber is None:
            issueNumber = input("please enter an issue number: ")
        else:
            print("issue number detected")
        print(issueNumber)

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='MyClass-command', help='Command to perform')
subparsers.required = True
startWorkParser = subparsers.add_parser('startwork', help='Command to begin work on a new branch')
startWorkParser.add_argument("issuenumber", type=int, help="The issue number used to create a local branch based on the specified issue number", nargs='?', default=None)
startWorkParser.set_defaults(func=MyClass.StartWork)

# Parse the arguments to make sure we have all the information requried to actually do something.
args = parser.parse_args()
mc = MyClass()

try:
    args.func(mc, **vars(args))
except AssertionError as e:
    print("Error: "+str(e))

# Parse the arguments to make sure we have all the information required to actually do something.
args = parser.parse_args()

我希望这样的电话:

python MyClass.py startwork

...导致提示用户输入问题编号.相反,我得到了:

...to result in the user being prompted for an issue number. Instead I get:

Traceback (most recent call last):
  File "C:\Projects\RedmnieGlue\MyClass.py", line 23, in <module>
    args.func(mc, **vars(args))
TypeError: StartWork() missing 1 required positional argument: 'issueNumber'

那为什么nargs='?'在这里不占主导地位?

So why is the nargs='?' not prevailing here?

修改

如果我这样称呼它:

python MyClass.py startwork -h

我明白了:

usage: class1.py startwork [-h] [issuenumber]

positional arguments:
  issuenumber  The issue number used to create a local branch based on the
               specified issue number

optional arguments:
  -h, --help   show this help message and exit

...(基于issuenumber周围的[])向我暗示理解这是一个可选参数,但是某些原因阻止了它的正常运行到.可能与我对subparsers的使用以及arg解析器调用方法有关吗?

...which (based on the [] around issuenumber) suggests to me it is understanding that is an optional argument but something is preventing it from working as I'd expect it to. Something to do with my use of subparsers and calling methods with the arg parser perhaps?

推荐答案

如果像这样在函数调用之前打印vars(args)的内容:

If you print the contents of vars(args) before your function call like this:

print(vars(args))
args.func(mc, **vars(args))

然后,您可以轻松地验证参数解析器是否存在问题.通过调用不带参数的脚本(例如python myscript.py),您将获得以下输出:

Then you can easily verify whether there is something wrong with the argument parser or not. With a call of the script without arguments (e.g. python myscript.py), you get the following output:

{'MyClass-command': 'startwork', 'issuenumber': None, 'func': <function MyClass.StartWork at 0x000000493898C510>}

如您所见,issuenumber实际上在该词典中,并且确实获得了默认值.因此,您看到的错误不是由于参数解析器引起的(它也不是argparse错误,因此对参数的验证(issuenumber是可选的)绝对正确).

As you can see issuenumber actually is in that dictionary, and it did get the default value. So the error you are seeing is not because of the argument parser (it’s also not an argparse error, so the validation on the arguments—with issuenumber being optional—is absolutely correct).

相反,出问题的是,在使用**vars(args)时,参数issuenumber没有传递给 positional 参数.不会发生的原因实际上很简单:

Instead, what’s going wrong is that the argument issuenumber is not passed to the positional argument when using **vars(args). The reason that does not happen is actually quite simply:

字典键是issuenumber;该函数需要一个issueNumber(请注意大写的N).因此,要么将函数更改为使用小写的issuenumber,要么将参数解析器更改为将该值存储在issueNumber 中.

The dictionary key is issuenumber; the function expects a issueNumber (note the upper case N). So either change the function to use a lowercase issuenumber, or change the argument parser to store the value in issueNumber instead.

这篇关于使用子解析器时,如何使argparse参数成为可选参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆