這裏有一個簡單的黑客,我放在一起,可能是一個合理的地方開始:
import argparse
class PositionalAction(argparse.Action):
def __call__(self,parser,namespace,values,option_string=None):
lst = getattr(namespace,self.dest)
lst.append(values)
parser.last_positional_values = lst
all_positional = getattr(namespace,'all_positional',[])
all_positional.append(lst)
namespace.all_positional = all_positional
class AssociateAction(argparse.Action):
def __call__(self,parser,namespace,values,option_string=None):
try:
parser.last_positional_values.append(values)
except AttributeError:
pass
parser = argparse.ArgumentParser()
parser.add_argument('-o',action=AssociateAction,dest=argparse.SUPPRESS)
junk,unknown = parser.parse_known_args()
for i,_ in enumerate(unknown):
parser.add_argument('arg%d'%i,action=PositionalAction,default=[])
print parser.parse_args()
這裏,它是在行動:
temp $ python test1.py foo -o 1 bar -o 2 baz qux -o 4
Namespace(all_positional=[['foo', '1'], ['bar', '2'], ['baz'], ['qux', '4']], arg0=['foo', '1'], arg1=['bar', '2'], arg2=['baz'], arg3=['qux', '4'])
這個問題有一些挑戰。首先,你想接受任意數量的位置參數 - argparse不喜歡那樣。 argparse想知道前面會發生什麼。解決方案是構建一個解析器並解析命令行,但要告訴argparse僅解析已知參數(在這種情況下,無位置-o
參數都是靜默解析,但「位置」參數未解析。) 。 parse_known_args
非常適合此操作,因爲它返回形式爲(namespace_of_parsed_stuff, uknown_args)
的元組。所以現在我們知道未知的參數 - 我們只需要爲解析器添加一個位置參數,以使parse_args高興。
現在,實際執行的自定義操作是什麼?當找到位置參數時(第二遍),我們得到默認值(這是一個列表)並將該值添加到該列表中(以下我將稱之爲「值」列表)。然後,我們修改解析器並參考「值」列表。我們還從命名空間中獲得「all_positional」列表。如果它沒有這個屬性,我們只是得到一個空的列表。我們將「value」列表添加到「all_positional」列表中並放回到名稱空間中。
現在,當我們點擊一個-o
標誌時,我們看解析器來獲取「值」列表,並且將附加值添加到該列表中。我們可以在不觸及解析器的情況下做同樣的事情......(我們可以看看namespace.all_positional[-1]
- 與parser.last_positional_values
的列表相同)。
你知道有多少位置參數嗎? – mgilson
不,我想循環參數,不管有多少。 – bkanuka