首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >argparse参数顺序

argparse参数顺序
EN

Stack Overflow用户
提问于 2012-01-27 07:28:31
回答 6查看 16K关注 0票数 21

我有个小问题。

我使用argparse来解析我的参数,它工作得很好。

为了获得参数,我这样做:

代码语言:javascript
复制
p_args = parser.parse_args(argv)
args = dict(p_args._get_kwargs())

但是p_args的问题是,我不知道如何将这些参数按照它们在命令行中的位置进行排序,因为这是一个字典。

那么有没有可能让元组/列表/有序字典中的参数按照它们在命令行中的顺序呢?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-01-27 09:50:01

为了保持参数的顺序,我使用了如下的自定义操作:

代码语言:javascript
复制
import argparse
class CustomAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        if not 'ordered_args' in namespace:
            setattr(namespace, 'ordered_args', [])
        previous = namespace.ordered_args
        previous.append((self.dest, values))
        setattr(namespace, 'ordered_args', previous)
parser = argparse.ArgumentParser()
parser.add_argument('--test1', action=CustomAction)
parser.add_argument('--test2', action=CustomAction)

要使用它,例如:

代码语言:javascript
复制
>>> parser.parse_args(['--test2', '2', '--test1', '1'])
Namespace(ordered_args=[('test2', '2'), ('test1', '1')], test1=None, test2=None)
票数 19
EN

Stack Overflow用户

发布于 2012-01-27 07:41:08

如果需要知道参数在解析器中的出现顺序,可以这样设置解析器:

代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser(description = "A cool application.")
parser.add_argument('--optional1')
parser.add_argument('positionals', nargs='+')
parser.add_argument('--optional2')

args = parser.parse_args()
print args.positionals

下面是一个运行此代码的快速示例:

代码语言:javascript
复制
$ python s.py --optional1 X --optional2 Y 1 2 3 4 5
['1', '2', '3', '4', '5']

请注意,args.positionals是一个按顺序排列位置参数的列表。有关详细信息,请参阅argparse documentation

票数 6
EN

Stack Overflow用户

发布于 2012-03-01 03:49:07

这有点脆弱,因为它依赖于对argparse.ArgumentParser内部原理的理解,但我使用的不是重写argparse.ArgumentParser.parse_known_args,而是以下内容:

代码语言:javascript
复制
class OrderedNamespace(argparse.Namespace):
    def __init__(self, **kwargs):
        self.__dict__["_arg_order"] = []
        self.__dict__["_arg_order_first_time_through"] = True
        argparse.Namespace.__init__(self, **kwargs)

    def __setattr__(self, name, value):
        #print("Setting %s -> %s" % (name, value))
        self.__dict__[name] = value
        if name in self._arg_order and hasattr(self, "_arg_order_first_time_through"):
            self.__dict__["_arg_order"] = []
            delattr(self, "_arg_order_first_time_through")
        self.__dict__["_arg_order"].append(name)

    def _finalize(self):
        if hasattr(self, "_arg_order_first_time_through"):
            self.__dict__["_arg_order"] = []
            delattr(self, "_arg_order_first_time_through")

    def _latest_of(self, k1, k2):
        try:
            print self._arg_order
            if self._arg_order.index(k1) > self._arg_order.index(k2):
                return k1
        except ValueError:
            if k1 in self._arg_order:
                return k1
        return k2

这是通过了解argparse.ArgumentParser.parse_known_args在为每个参数设置默认值后遍历整个选项列表而起作用的。这意味着用户指定的参数在__setattr__第一次遇到以前见过的参数时开始。

用法:

代码语言:javascript
复制
options, extra_args = parser.parse_known_args(sys.argv, namespace=OrderedNamespace())

您可以检查options._arg_order以了解用户指定的命令行参数的顺序,或者使用options._latest_of("arg1", "arg2")查看后来在命令行中指定了--arg1--arg2中的哪一个(对于我来说,这就是我所需要的:查看两个选项中哪一个是覆盖选项)。

更新: had添加了_finalize方法来处理列表中不包含任何参数的sys.argv()的病理情况)

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9027028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档