Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用argparse在单独的命名空间中拥有子解析器参数?_Python_Python 2.7_Argparse - Fatal编程技术网

Python 如何使用argparse在单独的命名空间中拥有子解析器参数?

Python 如何使用argparse在单独的命名空间中拥有子解析器参数?,python,python-2.7,argparse,Python,Python 2.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")

我有以下测试代码

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()
它定义了两个子解析器,具有不同的参数集。当我将测试代码调用为

tester.py  --verbose 3 car --boo 1 --foo 2
我得到了预期的结果

Namespace(boo='1', foo='2', parser_name='car', verbose=3)
我想要的是在一个单独的名称空间或dict中的每个子parser的值,类似于

Namespace(subparseargs={boo:'1', foo:'2'}, parser_name='car', verbose=3)
因此,每个子解析器的参数与主解析器的参数在逻辑上是分开的(本例中为
verbose


如果每个子parser的参数都在相同的命名空间中(
subparseargs
),我如何实现这一点呢?

您需要稍微了解一下
argparse
的内部,但将脚本更改为以下应该可以做到这一点:

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()

我已经开始开发一种不同的方法(但类似于Anthon的建议),并提出了一个更短的代码。然而,我不确定我的方法是否能解决这个问题

与Anthon的建议类似,我定义了一个新方法,它创建了一个“顶级”参数列表,这些参数保存在
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

欢迎对这种方法发表评论,特别是我忽略的漏洞。

并不能回答您的问题,但现代解析比原始解析更有趣。