【问题标题】:How to init argparser by looping instead of invoking `add_argument` for every argument manually?如何通过循环而不是手动为每个参数调用`add_argument`来初始化argparser?
【发布时间】:2020-11-28 13:44:35
【问题描述】:

使用argparser 创建 CLI 时,只要参数数量增加,代码就会开始显着重复。

可以通过文档中的example 看到:

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                    help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                    const=sum, default=max,
                    help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))

这是一个基本示例,以这种方式编写很好,但是可能会看到 add_argument 调用的重复。您可能会假设对于一个更复杂的 CLI,它很快就会成为一个问题。这是real example

有没有办法克服这个问题,使初始化更紧凑但仍然可读? (请不要对替代 CLI 框架提出建议)

更新澄清

我们一个接一个地用不同的参数重复调用同一个函数。我的直觉是,可能有一种方法可以将这些参数分组到一个结构中,然后在包含上述结构的列表中执行parser.add_argument,并结合使用星号/“双星号”运算符。

ArgumentParser.add_argument 具有以下声明:

ArgumentParser.add_argument(single positional argument, lots of optional keyword arguments)

我正在寻找一种数据结构以及可以解压缩到single positional argument, lots of optional keyword arguments 中的星号运算符。

【问题讨论】:

  • 除了函数名parser.add_argument(),没有重复。您希望得到什么样的改进?
  • 如果您有很多参数并且不想每次都在 CLI 中编写所有参数,您可以添加单个参数 --params param_file.json 并使用包含所有参数的 json 文件。 . 它很容易改变,只需要 1 个参数就可以得到相同的结果....它读起来更糟...但它有效。
  • 这不是问题。您只需将解析代码移动到单独的模块甚至包中。然后在你的主代码中调用from cli_parser import parse_args。类似的东西。
  • @hidden @barmar 也许另一种方法是从对列表中所有整数求和的角度来看。那么您是否还会争辩说,为列表的每个元素手动调用 add_to_sum() 与使用循环遍历列表并编写一次 add_to_sum() 一样好? :)
  • 您可以编写尽可能多的实用函数。 ipythonconfig 文件中设置其解析器复制变量。

标签: python argparse dry


【解决方案1】:

首先,我不认为它违反了 DRY。我们多次使用相同的函数,但不再重复其代码。

您在 cmets 中关于列表中整数求和的问题是什么,您建议使用 for 循环并调用一次“add_to_sum”函数。但是有什么反对将其应用于“add_argument”?

ARGS = (
    (('-x', '--crossbar'), {'type': str}),
    (('-c', '--config'), {'type': str})
)

parser = argparse.ArgumentParser()

for arg in ARGS:
    parser.add_argument(*arg[0], **arg[1])

【讨论】:

  • 感谢@hidden。您可能是对的,它没有违反“实用程序员”中定义的形式或最初定义的任何地方的 DRY。我想我不知道如何调用一个原则,最好是“循环遍历一个结构并编写一次函数调用,而不是每次都编写它而不使用循环”。还是有点不重复自己:p
猜你喜欢
  • 2020-11-02
  • 1970-01-01
  • 2013-10-20
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多