问题
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