2016-05-05 62 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]' –

相關問題