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