2013-10-01 36 views
4

我使用pythons(2.7.2)argparse(1.1)來解析命令行,我想要的是創建子分析器並使其可以多次輸入子分析器命令。像這樣:Python argparser重複子分區

./script.py version 1 --file 1 2 3 version 3 --file 4 5 6 

可以創建這樣的東西嗎?因爲現在當我嘗試在結果namespase中使用這樣的參數運行腳本時:

Namespace(file=['4', '5', '6'], n=[1]) 

n它是一個版本號。所以我得到第一個版本號和第二個文件列表,而不是文件列表和版本。

+0

您能否在問題中包含您當前的代碼? –

回答

4

對於主解析器,subparsers參數是一個需要選擇的位置。但它也將剩餘的所有參數字符串分配給子分析器。

我想到的是如下的字符串被解析:

./script.py version 1 --file 1 2 3 version 3 --file 4 5 6 

version被接受爲子分析器的名字。 1被接受爲位置參數n的值。 (子分析器的)。 --file被接受爲可選參數(由subparser)。第二個調用的值將覆蓋第一個的值。我猜0123'有nargs='*'。如果是這樣,第一個將['1','2','3','version','3']寫入名稱空間,而第二個用['4','5','6']覆蓋它。如果nargs=3,我會期望subparser嗆在第二個version,它會看作一個未知的位置。

所以基本的觀點是 - 一旦'版本'子分析器獲得參數列表,它就不會放手,直到它解析了所有可能的東西。在這種情況下,它解析--file事件。任何它無法處理的事情都會以「UNKNOWNS」的形式回到主解析器中,這通常會引發錯誤。


如果你想從重複自選值,使用追加行動

parser.add_argument('--foo',action='append', nargs=3) 

import argparse 
parser = argparse.ArgumentParser() 
sp = parser.add_subparsers(dest='version') 
spp = sp.add_parser('version') 
spp.add_argument('n',nargs='*',type=int) 
spp.add_argument('--file',nargs=3,action='append') 
str = 'version 1 --file 1 2 3 version 3 --file 4 5 6' 
print(parser.parse_known_args(str.split())) 

產生

(Namespace(file=[['1', '2', '3'], ['4', '5', '6']], n=[1], version='version'), ['version', '3']) 

仍然只有一個呼叫version子分析器,但所有的數據存在。


一種不同的方法將巢subparsers

parser = argparse.ArgumentParser() 
sp = parser.add_subparsers(dest='sub') 
spp = sp.add_parser('version') 
spp.add_argument('n',nargs=1,type=int) 
spp.add_argument('--file',nargs=3) 

sp = spp.add_subparsers(dest='sub1') 
spp = sp.add_parser('version') 
spp.add_argument('n1',nargs=1,type=int) 
spp.add_argument('--file',dest='file1',nargs=3) 

str = 'version 1 --file 1 2 3 version 3 --file 4 5 6' 
print(parser.parse_args(str.split())) 

請注意,我必須改變「DEST」,以避免過度書寫值。這會產生

Namespace(file=['1', '2', '3'], file1=['4', '5', '6'], n=[1], n1=[3], sub='version', sub1='version')