当前位置: 首页 > 面试题库 >

Argparse-不要用`nargs`捕获位置参数。

白泽语
2023-03-14
问题内容

我正在尝试编写一个函数wo,您可以通过argparse解析可变数量的参数-
我知道我可以通过做到这一点nargs="+"。可悲的是,argparse帮助的工作方式(以及人们通常在CLI中编写参数的方式)使位置参数处于最后位置。这导致我的位置参数被视为可选参数的一部分。

#!/usr/bin/python
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("positional", help="my positional arg", type=int)
parser.add_argument("-o", "--optional", help="my optional arg", nargs='+', type=float)
args = parser.parse_args()
print args.positional, args.optional

运行它,如./test.py -h下面的用法说明所示:

usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] positional

但是如果我跑步./test.py -o 0.21 0.11 0.33 0.13 100给我

test.py: error: too few arguments

为了获得正确的参数解析,我必须运行 ./test.py 100 -o 0.21 0.11 0.33 0.13

那么我该如何:

  • 使argparse重新格式化用法输出,以减少误导或更好:

  • 告诉argparse-o如果列表中的最后一个元素不捕获可选参数的最后一个元素


问题答案:

对此有一个错误报告:http :
//bugs.python.org/issue9338

带有nargs =’?’,’*’或’+’的argparse可选参数不能跟位置

一个简单的(用户)修复方法是--用来将位置和可选位置分开:

./test.py -o 0.21 0.11 0.33 0.13 -- 100

我写了一个补丁,保留了一些用于位置的参数。但这不是一件小事。

至于更改用法行,最简单的方法就是编写自己的用法,例如:

usage: test.py [-h] positional [-o OPTIONAL [OPTIONAL ...]]
usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] -- positional

我不建议在用法格式化程序中添加逻辑以进行此类更改。我认为这太复杂了。

另一个快速解决方案是将此位置转换为(必需)可选。它使用户可以完全自由地订购,并可以减少混乱。如果您不想混淆“ required
optional”,则给它一个逻辑上的默认值。

usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] -p POSITIONAL
usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] [-p POS_WITH_DEFAULT]

对Help_Formatter的一个简单更改是仅按照定义的顺序列出参数。修改格式化程序行为的通常方法是将其子类化,并更改一种或两种方法。这些方法大多数都是“专用”(_前缀),因此您意识到将来的代码可能会(缓慢地)更改。

在此方法中,actions是参数列表的定义顺序。默认行为是从“ positionals”中拆分“
optionals”,然后将列表结尾处的位置重新组合。还有其他代码可以处理需要换行的长行。通常,它将位置放在单独的行上。我已经省略了。

class Formatter(argparse.HelpFormatter):
    # use defined argument order to display usage
    def _format_usage(self, usage, actions, groups, prefix):
        if prefix is None:
            prefix = 'usage: '

        # if usage is specified, use that
        if usage is not None:
            usage = usage % dict(prog=self._prog)

        # if no optionals or positionals are available, usage is just prog
        elif usage is None and not actions:
            usage = '%(prog)s' % dict(prog=self._prog)
        elif usage is None:
            prog = '%(prog)s' % dict(prog=self._prog)
            # build full usage string
            action_usage = self._format_actions_usage(actions, groups) # NEW
            usage = ' '.join([s for s in [prog, action_usage] if s])
            # omit the long line wrapping code
        # prefix with 'usage:'
        return '%s%s\n\n' % (prefix, usage)

parser = argparse.ArgumentParser(formatter_class=Formatter)

产生如下用法行:

usage: stack26985650.py [-h] positional [-o OPTIONAL [OPTIONAL ...]]


 类似资料:
  • 我正在尝试编写一个函数,您可以通过argparse解析可变数量的参数--我知道我可以通过实现这一点。遗憾的是,argparse help的工作方式(以及人们通常在CLI中编写参数的方式)将位置参数放在最后。这导致我的位置参数作为可选参数的一部分被捕获。 要获得对参数的正确解析,我必须运行 那么我该如何: > 使argparse重新格式化用法输出,以减少误导,甚至更好:

  • 问题内容: 我有一个脚本,打算像这样使用: 是一个位置参数,其定义如下: 我希望它是可选的:未指定时,它应该只是。 不幸的是,当我不指定参数时,我得到了。 问题答案: 使用(或如果您需要多个目录) 扩展示例:

  • 问题内容: 试图解析可选的位置参数时,我遇到了以下问题: 例: 输出: 为什么不接受第三个程序调用?这是argparse的限制吗? 问题答案: 这是argparse的局限性,但在3.7中已部分取消。 Unix工具通常不声称支持选项和参数的混合,即使它们经常支持。问题在于将其与子命令等其他功能结合使用会导致歧义。因此,通常,支持所有这些功能的库都会在问题上出现问题,并且不允许混用。或者,他们做一些骇

  • 问题内容: 是否可以用来捕获任意一组可选参数? 例如,以下两个都应被接受为输入: 先验的 我不知道会指定哪些可选参数,但是会相应地处理它们。 问题答案: 这是一种黑客手段,但效果很好: 检查未添加的参数并添加它们 例如: 那么结果将是

  • 我有一些代码现在看起来有点像这样: 如您所见,我目前正在将对的调用包装在语句中,因为该函数可能会失败(它依赖于外部web服务调用)。 我的问题是:语句应该是a)在问题函数之外(就像我现在看到的那样)还是b)在问题函数内部? 谢谢。

  • 问题内容: 我有一个可选参数,它本身支持参数列表。 我的意思是,它应该支持: -f 1 2 -f 1 2 3 但不是: -f 1 -f 1 2 3 4 有没有办法在argparse中强制执行此操作?现在,我使用nargs =“ *”,然后检查列表长度。 编辑: 根据要求,我需要的是能够定义一个可接受数量的参数范围。我的意思是说(在示例中)2或3个args是正确的,但不是1或4或不在2..3范围内的