2014-03-25 77 views
4

我有一個字典,它將人類可讀值映射到三個不同的Python特定值。 argparse Python模塊如何使用這個字典來獲取特定的值,而用戶可以在這些鍵之間進行選擇。使用Python的字典argparse

目前我有這樣的:

def parse(a): 
    values = { "on": True, "off": False, "switch": None } 
    parser = argparse.ArgumentParser() 
    parser.add_argument("-v", "--value", choices=values, default=None) 
    args = parser.parse_args(a) 
    print("{}: {}".format(type(args.value), args.value)) 

>>> parse(['-v', 'on']) 
<type 'str'>: on 
>>> parse(['-v', 'off']) 
<type 'str'>: off 
>>> parse(['-v', 'switch']) 
<type 'str'>: switch 
>>> parse([]) 
<type 'NoneType'>: None 

的問題是,argparse不返回TrueFalseNone如果該參數給出。有沒有簡單的方法來添加此功能?當然,我將能夠執行像這樣算賬:

args.value = values[args.value] 

其實,這是我在做什麼目前,但這並不使用默認值很好地工作(我會檢查值已經是無或者默認設置爲"switch")。因爲我多次使用這個,所以每次都必須這樣做。

+0

指定'type = values .__ getitem__'就可以了。不知道,如果這是一個很好的解決方案,目前我很不舒服,所以我不知道我是否有好的想法。 – user2357112

+0

設置'default ='開關'有問題嗎?預先指定默認選擇是很好的做法。 – hpaulj

回答

3

變化最小的是使用

args.value = values.get(args.values) 

,所以你會得到沒有不在字典(如默認)的任何條目。

另一種選擇是濫用argparse的類型關鍵字:

values = { "on": True, "off": False, "switch": None } 
def convertvalues(value): 
    return values.get(value) 
parser.add_argument('-v','--value',type=convertvalues) 

「類型」的方法打破瞭如以上所使用的使用的選擇,因爲選擇在轉換之後應用。保持你的選擇使用一種可能性是:

def convertvalues(value): 
    return values.get(value,value) 
parser.add_argument('-v','--value',type=convertvalues, 
            choices=[True,False,None], 
            default=None) 

在這種情況下convertvalues返回,「關閉」,「開關」,並沒有被使用,如果「上」正確的價值觀,如果別的東西返回給定值(例如'bla')。由於'bla'不在選擇中,因此您會收到預期的錯誤消息。

使用「動作」與argparse.Action而不是類型派生的類應該做的工作聰明的辦法,如docs給出:

class DictAction(argparse.Action): 
    def __call__(self, parser, namespace, values, option_string=None): 
     value_dict = { "on": True, "off": False, "switch": None } 
     setattr(namespace, self.dest, value_dict.get(values)) 
parser.add_argument('-v','--value',action=DictAction, 
            choices=['on','off','switch'], 
            default=None) 

當然,這是不完美的,更好的解決方案會覆蓋Acion init以獲取字典並省略硬編碼的value_dict。

+0

我猜'type'參數應該設置爲'convertvalues'? – xZise

+0

好吧,當我使用'type'時,它告訴我parseargs:「argument -v/- value:invalid choice:False(from'on','switch','off')」 – xZise

+0

當然,它需要是convertvalues,對於錯字感到抱歉。對於你的第二個評論,我相信你留下了選擇。選擇做轉換後的比較,因此你需要做的選擇= values.values()。但是,由於您無法獲得任何輸入,因此此方法會破壞選擇。我會稍微更新答案的一些選擇。 – oekopez

0
values = { "on": True, "off": False, "switch": None } 
parser.add_argument("-v", "--value", choices=values.keys()) 
value = values.get(args.value) 
+0

'argparse'自動檢查字典鍵。 – hpaulj

0

我不能發表評論oekopez的回答, 但這種變化會使得用於傳遞到add_argument行動的任何字典可用的類。

class DictAction(argparse.Action): 
    def __call__(self, parser, namespace, values, option_string=None): 
     setattr(namespace, self.dest, self.choices.get(values, self.default)) 

value_dict = { "on": True, "off": False, "switch": None } 
parser.add_argument('-v','--value',action=DictAction, 
           choices=value_dict, 
           default=None)