Python:如何按字母顺序打印 argparse

问题描述 投票:0回答:1

我正在寻找一种规范的方式来按字母顺序打印

argparse
的返回参数:

import argparse
parser = argparse.ArgumentParser('Some program', add_help=False)
parser.add_argument('--bb', type=str)
parser.add_argument('--aa', type=str)
args = parser.parse_args()
print(args) # Output: Namespace(bb=..., aa=...), but I want aa appears before bb

提前谢谢你!

python argparse
1个回答
1
投票

argparse.Namespace
_AttributeHolder
的子类。产生显示的是它的
__repr__
方法。

class _AttributeHolder(object):
    """Abstract base class that provides __repr__.

    The __repr__ method returns a string in the format::
        ClassName(attr=name, attr=name, ...)
    The attributes are determined either by a class-level attribute,
    '_kwarg_names', or by inspecting the instance __dict__.
    """

    def __repr__(self):
        type_name = type(self).__name__
        arg_strings = []
        star_args = {}
        for arg in self._get_args():
            arg_strings.append(repr(arg))
        for name, value in self._get_kwargs():
            if name.isidentifier():
                arg_strings.append('%s=%r' % (name, value))
            else:
                star_args[name] = value
        if star_args:
            arg_strings.append('**%s' % repr(star_args))
        return '%s(%s)' % (type_name, ', '.join(arg_strings))
    def _get_kwargs(self):
        return list(self.__dict__.items())

所以你的解析器:

In [198]: args = parser.parse_args([])
In [199]: args
Out[199]: Namespace(bb=None, aa=None)
In [200]: args.__dict__
Out[200]: {'bb': None, 'aa': None}

显示顺序就是对象的顺序

__dict__
。具有默认值的属性在解析开始时放置在新的命名空间中,其顺序由
add_argument
命令的顺序决定。

In [206]: parser.parse_args(['--bb=xxx'], namespace=ns)
Out[206]: Namespace(aa='foo', bb='xxx')

更改此顺序的一种方法是事先创建一个命名空间对象,并将其传递给解析器。解析器不会添加任何已定义的默认值。用户输入可以改变值,但不会改变顺序:

In [207]: ns = argparse.Namespace(aa='foo', bb='bar')
In [208]: parser.parse_args([], namespace=ns)
Out[208]: Namespace(aa='foo', bb='bar')
In [209]: parser.parse_args(['--bb=xxx'], namespace=ns)
Out[209]: Namespace(aa='foo', bb='xxx')

您还可以定义一个自定义的

Namespace
类,它有自己的显示顺序,或者调整现有类的
__repr__

我依稀记得最初属性是排序的,并且一些相对较新的补丁改变了它。我必须检查错误/问题以查看是否是这种情况。

如评论中所述,您可以获取字典形式的命名空间

In [213]: vars(parser.parse_args([]))
Out[213]: {'bb': None, 'aa': None}

正如你评论的那样:

In [218]: argparse.Namespace(**dict(sorted(args.__dict__.items())))
Out[218]: Namespace(aa=None, bb=None)

最初

dict
顺序是不确定的,或者至少在某种程度上基于散列。不久前发生了变化,
dict
顺序由分配顺序决定。

© www.soinside.com 2019 - 2024. All rights reserved.