使用子解析器时如何使 argparse 参数可选?
How do I make an argparse argument optional when using subparsers?
我正在开发一个简单的 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
...导致提示用户输入问题编号。相反,我得到:
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='?'
在这里不流行?
编辑
如果我这样称呼它:
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 解析器调用方法有关?
如果像这样在函数调用前打印 vars(args)
的内容:
print(vars(args))
args.func(mc, **vars(args))
然后你可以很容易地验证参数解析器是否有问题。通过不带参数调用脚本(例如 python myscript.py
),您将获得以下输出:
{'MyClass-command': 'startwork', 'issuenumber': None, 'func': <function MyClass.StartWork at 0x000000493898C510>}
如您所见,issuenumber
实际上在该字典中,并且它确实获得了默认值。所以你看到的错误不是因为参数解析器(它也不是 argparse 错误,所以对参数的验证 - issuenumber
是可选的 - 是绝对正确的)。
相反,问题在于使用 **vars(args)
时参数 issuenumber
没有传递给 positional 参数。没有发生的原因其实很简单:
字典键是issuenumber
;该函数需要一个 issueNumber
(注意大写 N
)。因此,要么将函数更改为使用小写 issuenumber
,要么将参数解析器更改为 store the value in issueNumber
。
我正在开发一个简单的 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
...导致提示用户输入问题编号。相反,我得到:
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='?'
在这里不流行?
编辑
如果我这样称呼它:
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 解析器调用方法有关?
如果像这样在函数调用前打印 vars(args)
的内容:
print(vars(args))
args.func(mc, **vars(args))
然后你可以很容易地验证参数解析器是否有问题。通过不带参数调用脚本(例如 python myscript.py
),您将获得以下输出:
{'MyClass-command': 'startwork', 'issuenumber': None, 'func': <function MyClass.StartWork at 0x000000493898C510>}
如您所见,issuenumber
实际上在该字典中,并且它确实获得了默认值。所以你看到的错误不是因为参数解析器(它也不是 argparse 错误,所以对参数的验证 - issuenumber
是可选的 - 是绝对正确的)。
相反,问题在于使用 **vars(args)
时参数 issuenumber
没有传递给 positional 参数。没有发生的原因其实很简单:
字典键是issuenumber
;该函数需要一个 issueNumber
(注意大写 N
)。因此,要么将函数更改为使用小写 issuenumber
,要么将参数解析器更改为 store the value in issueNumber
。