2011-11-23 44 views
107

我認爲這一定很容易,但我不明白。argparse:確定使用哪個子分析器

假設我有以下arparse解析器:

import argparse 

parser = argparse.ArgumentParser(version='pyargparsetest 1.0') 
subparsers = parser.add_subparsers(help='commands') 

# all 
all_parser = subparsers.add_parser('all', help='process all apps') 

# app 
app_parser = subparsers.add_parser('app', help='process a single app') 
app_parser.add_argument('appname', action='store', help='name of app to process') 

我怎麼能確定,使用爲子分析器? 電話:

print parser.parse_args(["all"]) 

給我一個空的命名空間:

Namespace() 
+0

這個問題恕我直言有更好的回答則認爲一個原。 –

回答

56

編輯:請參閱quornian's answer這個問題,這是比我的好,應該是公認的答案。

根據argparse documentationparser.parse_args(...)的結果將「只包含主分析器和被選擇的子分析器的屬性」。不幸的是,這可能不足以確定使用哪個子分析器。文檔建議在子解析器上使用set_defaults(...)方法來解決此問題。

例如,我已經添加了調用set_defaults()到您的代碼:

import argparse 

parser = argparse.ArgumentParser(version='pyargparsetest 1.0') 
subparsers = parser.add_subparsers(help='commands') 

# all 
all_parser = subparsers.add_parser('all', help='process all apps') 
all_parser.set_defaults(which='all') 

# app 
app_parser = subparsers.add_parser('app', help='process a single app') 
app_parser.add_argument('appname', action='store', help='name of app to process') 
app_parser.set_defaults(which='app') 

現在,如果你運行

print parser.parse_args(["all"]) 

結果是

Namespace(which='all') 

退房的add_subparsers()有關更多信息和另一個示例的文檔。

+5

'set_defaults'很有用,就像在文檔中使用它將子命令綁定到一個函數的例子一樣..但是add_parser(dest ='which')似乎是「正確」的方法,因爲它不需要重複子命令名稱 – dbr

+1

@dbr是的,你是對的。夸爾尼安的答案應該是公認的答案。 – srgerg

+0

@dbr,應該是'add_subparsers(dest ='which')' – smac89

202

一個更簡單的解決方案是將dest添加到add_subparsers調用。這是埋位在documentation進一步下跌:

[...]如果需要檢查被調用的子分析器的名稱,DEST關鍵字參數到add_subparsers()調用將工作

在您的例子取代:

subparsers = parser.add_subparsers(help='commands') 

有:

subparsers = parser.add_subparsers(help='commands', dest='command') 

現在,如果你運行:

print parser.parse_args(["all"]) 

你會得到

Namespace(command='all') 
+0

這似乎是正確的方式,因爲它的作用就像任何其他參數上的'dest'參數(只有它默認爲'None',而不是被拉從'--longopt'值)。使用'set_defaults'似乎不適用於此(但對其他事情有用) – dbr

+0

這是正確的答案!如果能夠測試「命令」值,將會很好。 –

+0

順便說一句,如果在同一個類中有函數可以執行的命令的名稱:「getattr(self,args.command)()」按名稱執行它! –

相關問題