Is there a way to get the argument of argparse in the order in which they were defined?

*爱你&永不变心* 提交于 2019-12-24 08:03:35

问题


I'd like to print all options of the program and they are grouped for readability. However when accessing the arguments via vars(args), the order is random.


回答1:


argparse parses the list of arguments in sys.argv[1:] (sys.argv[0] is used as the prog value in usage).

args=parser.parse_args() returns a argparse.Namespace object. vars(args) returns a dictionary based on this object (args.__dict__). Keys of a dictionary are unordered. print(args) also uses this dictionary order.

The parser keeps a record of seen-actions for its own bookkeeping purposes. But it is not exposed to the user, and is an unordered set. I can imagine defining an custom Action subclass that recorded the order in which its instances were used.


It is possible to retrieve arguments in the order in which they were defined when creating the parser. That's because the parser has a _actions list of all the Actions. It's not part of the public API, but a basic attribute and unlikely to every disappear.

To illustrate:

In [622]: parser=argparse.ArgumentParser()
In [623]: parser.add_argument('foo')
In [624]: parser.add_argument('--bar')
In [625]: parser.add_argument('--baz')

In [626]: parser.print_help()
usage: ipython3 [-h] [--bar BAR] [--baz BAZ] foo

positional arguments:
  foo

optional arguments:
  -h, --help  show this help message and exit
  --bar BAR
  --baz BAZ

The usage and help listings show the arguments in the order that they are defined, except that positionals and optionals are separated.

In [627]: args=parser.parse_args(['--bar','one','foobar'])
In [628]: args
Out[628]: Namespace(bar='one', baz=None, foo='foobar')
In [629]: vars(args)
Out[629]: {'bar': 'one', 'baz': None, 'foo': 'foobar'}

In [631]: [(action.dest, getattr(args,action.dest, '***')) for action in parser._actions]
Out[631]: [('help', '***'), ('foo', 'foobar'), ('bar', 'one'), ('baz', None)]

Here I iterate on the _actions list, get the dest for each Action, and fetch that value from the args namespace. I could have fetched it from the vars(args) dictionary just as well.

I had to give getattr a default ***, because the help action does not appear in the namespace. I could have filtered that sort of action out of the display.



来源:https://stackoverflow.com/questions/39282429/is-there-a-way-to-get-the-argument-of-argparse-in-the-order-in-which-they-were-d

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!