2016-05-05 36 views
0

我正在研究一个简单的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解析器调用方法有什么关系?

+0

我能够无任何错误地运行此代码。 –

+1

(1)'def StartWork(...)'中有一个语法错误(缺少尾部冒号)。 (2)错误信息与显示的代码不匹配(例如,没有'Main'功能),所以在你的代码中出现的错误不会在你的简化版本中显示。 – poke

+0

这是试图将原始代码削减为可行的例子。我会解决它,所以它是一个完整的工作解决方案... –

回答

2

如果你的函数调用之前打印的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未传递给位置参数。没有发生的原因实际上很简单:

字典关键是issuenumber;该函数需要issueNumber(注意大写N)。因此,要么将函数更改为使用小写issuenumber,要么改为将参数解析器更改为store the value in issueNumber

+0

在StartWork方法的定义中发现错误@poke的源头并设置了'issueNumber = None'后,一旦该方法的情况与参数定义的情况匹配,就会按预期工作。 –

+0

只需再注意一点;当设置名称时,它总是匹配'StartWork'所需的名称,这非常有效:'inspect.getargspec(MyClass.StartWork).args [1]' –

相关问题