我正在寻找一种规范的方式来按字母顺序打印
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
提前谢谢你!
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
顺序由分配顺序决定。