Python 使用子parser时,如何使argparse参数成为可选参数?

Python 使用子parser时,如何使argparse参数成为可选参数?,python,argparse,Python,Argparse,我正在编写一个简单的Git/Redmine粘合脚本,但是在Pythonargparse模块中使用可选参数时遇到了一些困难 使用以下代码: import argparse class MyClass: def StartWork(self, issueNumber, **kwargs): if issueNumber is None: issueNumber = input("please enter an issue number: ")

我正在编写一个简单的Git/Redmine粘合脚本,但是在Python
argparse
模块中使用可选参数时遇到了一些困难

使用以下代码:

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
python MyClass.py startwork -h
print(vars(args))
args.func(mc, **vars(args))
…导致提示用户输入问题编号。相反,我得到:

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'
我明白了:

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

…这(基于
issuember
周围的
[]
)向我表明,理解是一个可选的参数,但某些因素阻止了它按我的预期工作。可能与我使用
子parser
和使用arg解析器调用方法有关?

如果在函数调用之前打印
变量(args)
的内容,如下所示:

python MyClass.py startwork
python MyClass.py startwork -h
print(vars(args))
args.func(mc, **vars(args))
然后,您可以轻松地验证参数解析器是否有问题。通过调用不带参数的脚本(例如,
python myscript.py
),您将获得以下输出:

{'MyClass-command': 'startwork', 'issuenumber': None, 'func': <function MyClass.StartWork at 0x000000493898C510>}
{'MyClass-command':'startwork','issuember':无,'func':}
正如您所看到的,issuenumber实际上在该字典中,它确实得到了默认值。因此,您看到的错误不是因为参数解析器(它也不是argparse错误,因此对
issuember
为可选参数的验证是绝对正确的)

相反,问题是在使用
**变量(args)
时,参数
issuenumber
没有传递给位置参数。没有发生的原因其实很简单:


字典键是
issuenumber
;函数需要一个
issueNumber
(注意大写的
N
)。因此,如果在函数调用之前打印
vars(args)
的内容,可以将函数更改为使用小写的issuenumber,也可以将参数解析器更改为。

python MyClass.py startwork
python MyClass.py startwork -h
print(vars(args))
args.func(mc, **vars(args))
然后,您可以轻松地验证参数解析器是否有问题。通过调用不带参数的脚本(例如,
python myscript.py
),您将获得以下输出:

{'MyClass-command': 'startwork', 'issuenumber': None, 'func': <function MyClass.StartWork at 0x000000493898C510>}
{'MyClass-command':'startwork','issuember':无,'func':}
正如您所看到的,issuenumber实际上在该字典中,它确实得到了默认值。因此,您看到的错误不是因为参数解析器(它也不是argparse错误,因此对
issuember
为可选参数的验证是绝对正确的)

相反,问题是在使用
**变量(args)
时,参数
issuenumber
没有传递给位置参数。没有发生的原因其实很简单:


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

我可以运行此代码而不会出现任何错误。(1)def StartWork(…)中存在语法错误(缺少尾随冒号)。(2) 错误消息与显示的代码不匹配(例如,没有
Main
函数),因此您的简化版本中不会显示代码的任何错误。这是试图将原始代码精简为一个可行的示例。我会修正它,使它成为一个完整的工作解决方案…@poke-现在试一试。你是不是把给脚本的参数和函数StartWork得到的参数混为一谈了?
def StartWork(self,issuember=None,**kwargs):
解决了您的问题吗?我能够运行此代码而没有任何错误。(1)def StartWork(…)中存在语法错误(缺少尾随冒号)。(2) 错误消息与显示的代码不匹配(例如,没有
Main
函数),因此您的简化版本中不会显示代码的任何错误。这是试图将原始代码精简为一个可行的示例。我会修正它,使它成为一个完整的工作解决方案…@poke-现在试一试。你是不是把给脚本的参数和函数StartWork得到的参数混为一谈了?不
def StartWork(self,issueNumber=None,**kwargs):
解决您的问题?在
StartWork
方法定义中的错误@poke和setting
issueNumber=None
的来源上,只要方法的大小写与参数定义的大小写匹配,它就会按预期工作;当设置名称以使其始终符合
StartWork
的要求时,这非常有效:
inspect.getargspec(MyClass.StartWork).args[1]
StartWork
方法定义中的错误源@poke和setting
issueNumber=None
上有很好的定位,一旦该方法的大小写与参数定义的大小写匹配,它就会按预期工作;当设置名称以使其始终符合
StartWork
的要求时,此操作非常有效:
inspect.getargspec(MyClass.StartWork).args[1]