获取argparse中的其余参数

ggo*_*oha 42 python argparse

我想立刻获得所有剩余的未使用的参数.我该怎么做?

parser.add_argument('-i', action='store', dest='i', default='i.log')
parser.add_argument('-o', action='store', dest='o', default='o.log')
Run Code Online (Sandbox Code Playgroud)

Elm*_*ise 82

用途parse_known_args():

args, unknownargs = parser.parse_known_args()
Run Code Online (Sandbox Code Playgroud)

  • 当未知参数可以有前导破折号时,这很有用.例如,您将它们传递给另一个脚本. (7认同)
  • *这*应该是接受的答案! (3认同)
  • 似乎有两种解决方案可以为包装命令提取可能存在冲突的参数:1)使用`argparse.REMAINDER`在最后一次已知/预期之后收集剩余的参数,或者2)在命令中用`--`分隔包装的命令线. (3认同)
  • 当您希望参数具有[参数中断]时,请使用“argparse.REMAINDER”(https://unix.stackexchange.com/questions/147143/when-and-how-was-the-double-dash-introduced-as-选项结束分隔符)需要“--”。当您想要透明地使用多个 ArgumentParser 时,例如使用接受参数的共享库,请使用 .parse_known_args 。 (3认同)

sma*_*c89 43

用途argparse.REMAINDER:

parser.add_argument('rest', nargs=argparse.REMAINDER)
Run Code Online (Sandbox Code Playgroud)

例:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', action='store', dest='i', default='i.log')
parser.add_argument('-o', action='store', dest='o', default='o.log')
parser.add_argument('rest', nargs=argparse.REMAINDER)
parser.parse_args(['hello', 'world'])
>>> Namespace(i='i.log', o='o.log', rest=['hello', 'world'])
Run Code Online (Sandbox Code Playgroud)

  • 对于你要包装另一个命令的情况,这是IMO最好的解决方案:`wrapper.py --help` - >你的帮助文本`wrapper.py some args --help` - >传递给包装命令 (6认同)
  • `argparse.REMAINDER` 现在没有记录并被认为是遗留的,但我不相信它会很快被删除。参见https://github.com/python/cpython/pull/18661 (3认同)

Quu*_*one 26

我去编写了这个帖子中作为答案给出的三个建议.测试代码显示在此答案的底部.结论:到目前为止nargs=REMAINDER,最好的全能答案是,但它可能真的取决于您的用例.

以下是我观察到的差异:

(1)nargs=REMAINDER赢得用户友好性测试.

$ python test.py --help
Using nargs=*          : usage: test.py [-h] [-i I] [otherthings [otherthings ...]]
Using nargs=REMAINDER  : usage: test.py [-h] [-i I] ...
Using parse_known_args : usage: test.py [-h] [-i I]
Run Code Online (Sandbox Code Playgroud)

(2)在命令行上nargs=*静默过滤出第一个--参数,这看起来很糟糕.另一方面,所有方法都尊重--作为一种方式来说"请不要将这些字符串解析为已知的args".

$ ./test.py hello -- -- cruel -- -- world
Using nargs=*          : ['hello', '--', 'cruel', '--', '--', 'world']
Using nargs=REMAINDER  : ['hello', '--', '--', 'cruel', '--', '--', 'world']
Using parse_known_args : ['hello', '--', '--', 'cruel', '--', '--', 'world']

$ ./test.py -i foo -- -i bar
Using nargs=*          : ['-i', 'bar']
Using nargs=REMAINDER  : ['--', '-i', 'bar']
Using parse_known_args : ['--', '-i', 'bar']
Run Code Online (Sandbox Code Playgroud)

(3)除了parse_known_argsdie 之外的任何方法,如果它试图解析以字符串开头-并且结果证明无效.

$ python test.py -c hello
Using nargs=*          : "unrecognized arguments: -c" and SystemExit
Using nargs=REMAINDER  : "unrecognized arguments: -c" and SystemExit
Using parse_known_args : ['-c', 'hello']
Run Code Online (Sandbox Code Playgroud)

(4)nargs=REMAINDER当它遇到第一个未知参数时完全停止解析.parse_known_args会吞噬"已知"的论点,无论它们出现在哪一行(并且如果它们看起来不正确就会死亡).

$ python test.py hello -c world
Using nargs=*          : "unrecognized arguments: -c world" and SystemExit
Using nargs=REMAINDER  : ['hello', '-c', 'world']
Using parse_known_args : ['hello', '-c', 'world']

$ python test.py hello -i world
Using nargs=*          : ['hello']
Using nargs=REMAINDER  : ['hello', '-i', 'world']
Using parse_known_args : ['hello']

$ python test.py hello -i
Using nargs=*          : "error: argument -i: expected one argument" and SystemExit
Using nargs=REMAINDER  : ['hello', '-i']
Using parse_known_args : "error: argument -i: expected one argument" and SystemExit
Run Code Online (Sandbox Code Playgroud)

这是我的测试代码.

#!/usr/bin/env python

import argparse
import sys

def using_asterisk(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', dest='i', default='i.log')
    parser.add_argument('otherthings', nargs='*')
    try:
        options = parser.parse_args(argv)
        return options.otherthings
    except BaseException as e:
        return e

def using_REMAINDER(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', dest='i', default='i.log')
    parser.add_argument('otherthings', nargs=argparse.REMAINDER)
    try:
        options = parser.parse_args(argv)
        return options.otherthings
    except BaseException as e:
        return e

def using_parse_known_args(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', dest='i', default='i.log')
    try:
        options, rest = parser.parse_known_args(argv)
        return rest
    except BaseException as e:
        return e

if __name__ == '__main__':
    print 'Using nargs=*          : %r' % using_asterisk(sys.argv[1:])
    print 'Using nargs=REMAINDER  : %r' % using_REMAINDER(sys.argv[1:])
    print 'Using parse_known_args : %r' % using_parse_known_args(sys.argv[1:])
Run Code Online (Sandbox Code Playgroud)

  • 你至少节省了我一个小时的时间。为什么官方文档中没有这一部分?‍♀️ (3认同)

Sin*_*ion 17

另一个选择是向解析器添加位置参数.指定不带前导破折号的选项,并argparse在未识别其他选项时查找它们.这具有改进命令的帮助文本的额外好处:

>>> parser.add_argument('otherthings', nargs='*')
>>> parser.parse_args(['foo', 'bar', 'baz'])
Namespace(i='i.log', o='o.log', otherthings=['foo', 'bar', 'baz'])
Run Code Online (Sandbox Code Playgroud)

>>> print parser.format_help()
usage: ipython-script.py [-h] [-i I] [-o O] [otherthings [otherthings ...]]

positional arguments:
  otherthings

optional arguments:
  -h, --help   show this help message and exit
  -i I
  -o O
Run Code Online (Sandbox Code Playgroud)