Python argparse with nargs behaviour incorrect

六月ゝ 毕业季﹏ 提交于 2019-12-01 11:00:49
hpaulj

To produce a list of ['x','y'] use action='append'. Actually it gives

Namespace(p=[['x'], ['y']])

For each -p it gives a list ['x'] as dictated by nargs='+', but append means, add that value to what the Namespace already has. The default action just sets the value, e.g. NS['p']=['x']. I'd suggest reviewing the action paragraph in the docs.

optionals allow repeated use by design. It enables actions like append and count. Usually users don't expect to use them repeatedly, or are happy with the last value. positionals (without the -flag) cannot be repeated (except as allowed by nargs).

How to add optional or once arguments? has some suggestions on how to create a 'no repeats' argument. One is to create a custom action class.

I ran into the same issue. I decided to go with the custom action route as suggested by mgilson.

import argparse
class ExtendAction(argparse.Action):
  def __call__(self, parser, namespace, values, option_string=None):
    if getattr(namespace, self.dest, None) is None:
      setattr(namespace, self.dest, [])
    getattr(namespace, self.dest).extend(values)
parser = argparse.ArgumentParser()
parser.add_argument("-p", nargs="+", help="Stuff", action=ExtendAction)
args = parser.parse_args()
print args

This results in

$ ./sample.py -p x -p y -p z w
Namespace(p=['x', 'y', 'z', 'w'])

Still, it would have been much neater if there was an action='extend' option in the library by default.

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