本文介绍了使用子解析器时如何使 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 参数可选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-15 22:04