2013-04-03 17 views
7

我有以下的測試碼如何使用argparse在單獨的命名空間中使用子分析器參數?

import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument("--verbose", default = 0, type=int) 

subparsers = parser.add_subparsers(dest = "parser_name") 

parser_lan = subparsers.add_parser('car') 
parser_lan.add_argument("--boo") 
parser_lan.add_argument("--foo") 

parser_serial = subparsers.add_parser('bus') 
parser_serial.add_argument("--fun") 

print parser.parse_args() 

其限定兩個子解析器,具有一組不同的參數。當我打電話testcode作爲

tester.py --verbose 3 car --boo 1 --foo 2 

我得到預期的結果

Namespace(boo='1', foo='2', parser_name='car', verbose=3) 

我想擁有,而不是從一個單獨的命名空間或字典的每個子分析器,像

Namespace(subparseargs={boo:'1', foo:'2'}, parser_name='car', verbose=3) 
東西值

以便來自每個子分析器的參數與主分析器的參數邏輯分離(如本例中的verbose)。

我怎樣才能做到這一點,用的參數在同命名空間每個子分析器(subparseargs中的例子)。

+0

不回答你的問題,但現代[argparse包裝](http://stackoverflow.com/q/13248487/989121)比原始argparse更有趣。 – georg

回答

1

我已經開始開發不同的方法(但類似於安森建議),並拿出一個更短的代碼。但是,我不確定我的方法是否是解決問題的一般方法。

類似什麼安森提議,我定義它創建的被保存在args「頂級」參數列表的新方法,而所有其他參數都作爲額外的字典返回:

class MyArgumentParser(argparse.ArgumentParser): 
    def parse_subargs(self, *args, **kw): 
     # parse as usual 
     args = argparse.ArgumentParser.parse_args(self, *args, **kw) 

     # extract the destination names for top-level arguments 
     topdest = [action.dest for action in parser._actions] 

     # loop over all arguments given in args 
     subargs = {} 
     for key, value in args.__dict__.items(): 

      # if sub-parser argument found ... 
      if key not in topdest: 

       # ... remove from args and add to dictionary 
       delattr(args,key) 
       subargs[key] = value 

     return args, subargs 

對這種方法的評論很受歡迎,尤其是我忽略的任何漏洞。

2

你需要進入的​​深處一下,但改變你的腳本,下面應該做的伎倆:

import argparse 
from argparse import _HelpAction, _SubParsersAction 

class MyArgumentParser(argparse.ArgumentParser): 
    def parse_args(self, *args, **kw): 
     res = argparse.ArgumentParser.parse_args(self, *args, **kw) 
     from argparse import _HelpAction, _SubParsersAction 
     for x in parser._subparsers._actions: 
      if not isinstance(x, _SubParsersAction): 
       continue 
      v = x.choices[res.parser_name] # select the subparser name 
      subparseargs = {} 
      for x1 in v._optionals._actions: # loop over the actions 
       if isinstance(x1, _HelpAction): # skip help 
        continue 
       n = x1.dest 
       if hasattr(res, n): # pop the argument 
        subparseargs[n] = getattr(res, n) 
        delattr(res, n) 
      res.subparseargs = subparseargs 
     return res 

parser = MyArgumentParser() 
parser.add_argument("--verbose", default = 0, type=int) 

subparsers = parser.add_subparsers(dest = "parser_name") 

parser_lan = subparsers.add_parser('car') 
parser_lan.add_argument("--boo") 
parser_lan.add_argument("--foo") 

parser_serial = subparsers.add_parser('bus') 
parser_serial.add_argument("--fun") 

print parser.parse_args() 
相關問題