【问题标题】:Variable-length argparse argument lists可变长度 argparse 参数列表
【发布时间】:2020-09-17 23:07:20
【问题描述】:

我希望将一组参数传递到具有等量 inputsoutputs 参数的脚本中。我知道我可以按照以下方式解析

inputs, outputs = sys.argv[:halfway], sys.argv[halfway:]

考虑到sys.argv[0] 是名称,但我想要argparse 的有用功能。

我也知道我可以将代码更改为parser.add_argument('-i', 'inputs', nargs='+'),这样我就可以将我的参数指定为python testarg.py -i 1 2 -o 3 4,但我不想使用那种语法,因为已经有一个输入,一个 -输出python testarg.py input output,我想通过制作语法python testarg.py inputs[...] outputs[...]来保留它

这是我得到的最接近的

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('inputs', nargs='+')
parser.add_argument('outputs', nargs='+')
print(parser.parse_args())
$ python testarg.py 1
usage: testarg.py [-h] input [input ...] output [output ...]
testarg.py: error: the following arguments are required: output

$ python testarg.py 1 2
Namespace(inputs=['1'], outputs=['2'])

$ python testarg.py 1 2 3 4
Namespace(inputs=['1', '2', '3'], outputs=['4'])

我想要

Namespace(inputs=['1', '2'], outputs=['3', '4'])

【问题讨论】:

  • 我认为它没有这个功能,使用-i-o会更简单
  • 输入和输出是如何工作的?我认为将它们配对可能更有意义,例如testarg.py input output [--io input output] ...。这样您就可以使用 nargs=2 为您验证数字。
  • input output [input output]... 是另一种可以大大减少解析工作的方法(只需让 argparse 读取 one 列表,然后检查它是否有偶数个项目并报告它否则作为使用错误 - 有一种方便的方法)。
  • 谢谢,对input output [input output]...可能是更简单的方法,我没想到!

标签: python argparse


【解决方案1】:

click 库可以做到这一点,它支持可以修改参数值的回调函数。

import click


def split_args(context, param, value):
    num_args = len(value)
    if num_args % 2:
        raise click.BadParameter(
            f"Must provide an even number of arguments, got {num_args} arguments"
        )
    midpoint = num_args // 2
    return value[:midpoint], value[midpoint:]


@click.command()
@click.argument("args", callback=split_args, nargs=-1)
def io(args):
    inputs, outputs = args
    print("inputs: ", inputs)
    print("outputs: ", outputs)


if __name__ == "__main__":
    io()
$ python3 testarg.py 1 2 3 4
inputs:  ('1', '2')
outputs:  ('3', '4')

【讨论】:

    【解决方案2】:

    nargs 模仿(甚至使用)regex 通配符量词

    在这种情况下:

    Namespace(inputs=['1', '2', '3'], outputs=['4'])
    

    一个值已分配给outputs(因为它是“一个或多个”),其余的“更多”分配给inputs

    现在如果你能接受

    python prog.py --inputs 1 2 --outputs 3 4
    

    “+”会按预期工作。

    但是对于可变长度位置(或可选后跟位置),没有办法告诉它第一个列表在哪里结束,第二个从哪里开始。

    当然,如果您喜欢 argparse 帮助,您可以在解析后调整列表平衡 - 例如将“3”移动到另一个列表。调整解析的值没有错。在解析器本身中执行所有操作不会获得额外的“好孩子”积分。

    【讨论】:

      猜你喜欢
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 2011-11-27
      • 1970-01-01
      • 2020-03-14
      • 2017-02-06
      相关资源
      最近更新 更多