2012-06-30 67 views
5

我想將位置參數與它們出現時存在的「參數狀態」相關聯。例如,以下命令行:可以argparse將位置參數與命名參數關聯嗎?

script.py -m 1 foo -r 2 bar -r 7 baz -m 6 quux 

應該產生如下聯想:

foo: m=1, r=0 (default value for r) 
bar: m=1, r=2 
baz: m=1, r=7 
quux: m=6, r=7 

這能與​​模塊做了什麼?

+0

「參數狀態」的集合是否爲常量?例如如果只有'('foo','bar','baz','quux'...)會被使用,你知道嗎?或者用戶能夠隨意放置任何他們想要的東西? – mgilson

+0

@mgnilson - 任何他們想要的地方;我正在看的是文件名和處理選項的列表。基於'argparse'處理位置參數,我想這不能沒有破壞模型的自定義Action,這是我目前正在玩的。 –

+0

我也在考慮自定義操作,但這很棘手,因爲argparse似乎認爲所有位置參數都放在一起。唯一的補救辦法是在任何地方使用'nargs ='*'',然後在你的所有行動中檢查以確保你得到了正確的數字。 (最好看起來很脆弱)。當然,如果你允許:-m 1 -f foo -r 2 -f bar -r 7 -f baz -m 6 -f quux' – mgilson

回答

1

這可能對您沒有用處,但是如果您可以將sys.argv分解成幾部分,這個問題似乎是最簡單的 - 基本上,您需要能夠找出哪些部分應該是「位置」參數(他們'因爲你說的不是實際的位置,它們可能發生在任何地方),哪些部分應該是某種論點。在下面的示例中,我已經將它設置爲與您的示例一起工作,但您可以輕鬆地將sys.argv分割爲文件或某種文件。 condition函數由您來編寫。其餘的將(希望)是不言自明的。

import argparse 
import sys 
import copy 
import os 

def split_list(lst,condition): 
    current=[] 
    out=[current] 
    for arg in lst: 
     current.append(arg) 
     if(condition(arg)): 
      current=[] 
      out.append(current) 

    return out 


parser=argparse.ArgumentParser() 
parser.add_argument('-m',action='store') 
parser.add_argument('-r',default='0',action='store') 
#pieces=split_list(sys.argv[1:],os.path.isfile) 
pieces=split_list(sys.argv[1:],lambda x: x in ('foo','bar','baz','quux')) 
options={} #use collections.OrderedDict if order matters -- or some more suitable data structure. 
default=argparse.Namespace() 
for args in pieces: 
    if(not args): 
     continue 
    ns=copy.deepcopy(default) 
    default=parser.parse_args(args[:-1],namespace=ns) 
    options[args[-1]]=default 

print (options) 
+0

有趣的想法!改變lambda爲'x [0]!=「 - 」'應該有效地分割參數(我認爲我提出的基本語法使得接受以'-'開頭的文件名是不合理的)。讓我玩這個。 –

+0

@BenBlank將lambda更改爲'not x.startswith(' - ')'是我的第一個想法,但它在測試示例上失敗,因爲'1'不以''開始 - – mgilson

+0

我通過[替換帶有硬編碼邏輯的lambda(https://gist.github.com/3026853),它拒絕在命名參數後分裂。隨着這種變化,這正是我所需要的!謝謝您的幫助。 –

相關問題