如何将 kwargs 传递给 argparse

Posted

技术标签:

【中文标题】如何将 kwargs 传递给 argparse【英文标题】:How to pass kwargs to argparse 【发布时间】:2020-06-30 19:04:26 【问题描述】:

我需要通过命令行将字典传递给 python 模块。我还没有找到让 Python 合作的方法。以下是我想要完成的一个非常简化的示例。这会产生以下错误TypeError: _get_positional_kwargs() missing 1 required positional argument: 'dest' 。在 add_argument 行中添加 dest 参数会导致 TypeError: __init__() got an unexpected keyword argument 'kwargs',这表明 argparse 可能根本不会将字典作为参数。 pickle 文件真的是在命令行调用中来回传递字典的唯一选择吗?

def run(**kwargs):
for i in kwargs.items():
    print(f'i: kwargs[i]')
# ...some code to manipulate the dictionary
return kwargs


if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Test script")
parser.add_argument(kwargs='**', description='A dictionary to be manipulated and returned')
args = parser.parse_args()
x = run(args)
pass

其他信息 - 我知道我可以使用包含空格分隔参数的命令行将列表传递给 *nargs 参数,但我需要对字典执行类似操作。

更新 - 工作原理: 根据@chepner 的有用输入,我能够让它与他在回答中提到的 json 解决方案一起工作。在我的 Windows 平台上,我确实必须从字典字符串中删除所有空格,并且最终命令行字符串中需要转义字符。

\"this\":1,\"is\":2,\"a\":5,\"dictionary\":7

【问题讨论】:

“向 add_argument 行添加 dest 参数” - 我在您的代码中没有看到任何名为 dest 的参数。您正在尝试传递一个名为 kwargs 的参数,但调用者无法直接访问它。您必须像使用 description="thing" 一样传递 kwargs add_argument() 至少需要一个位置参数。您想要实现什么,您希望传递给run() 的字典的键和值包含什么? 您能否添加一个模块的命令行调用示例,帮助我们了解您想要做什么? 命令行参数示例可能类似于:C:\Python37\python.exe test.py -this 1 -is 2 -a 3 -dictionary 4。在正常情况下,我会传递数百甚至数千个键值对。命令行调用将由代码生成。 可能无法传递数千个参数,具体取决于您的操作系统。 【参考方案1】:

参数是字符串,句号。您要传递的是包含 编码 dict 的字符串,例如使用 JSON。

import argparse
import json


parser = argparse.ArgumentParser()
parser.add_argument('data', type=json.loads)

args = parser.parse_args()

如果你用类似的东西运行你的脚本

myscript '"foo": 3, "bar": "hello"'

然后是args.data["foo"] == 3args.data["bar"] == "hello"

【讨论】:

基本思路是有道理的,但还行不通。如果我通过'"this": 1, "is": 2, "a": 3, "dictionary": 4'(单引号,双引号没有区别)我得到一个错误:error: argument data: invalid loads value: 'this:' 您是如何准确运行脚本的?这是我在使用./myscript.py "this": 1, "is": 2, "a": 3, "dictionary": 4 而不是./myscript.py '"this": 1, "is": 2, "a": 3, "dictionary": 4' 时得到的错误(从bash 运行脚本时)。 (引号很重要;JSON 本身必须使用双引号,而单引号可防止 shell 在调用 myscript.py 之前执行分词和引号删除。) 更简单地说:您以某种方式将多个参数 this:1, is: 等传递给您的脚本,而不是单个参数 "this": 1, "is": 2, ... 在这种情况下,我在 Windows 机器上使用 PyCharm,但命令提示符下的错误是相同的:C:\>python "C:\test\test.py" '"this": "1", "is": "2", "a": "5", "dictionary": "7"' usage: test.py [-h] data test.py: error: argument data: invalid loads value: "'this:" 这些都是特定于平台的问题,如何向 Python 提供单个字符串参数,与 Python 本身无关。

以上是关于如何将 kwargs 传递给 argparse的主要内容,如果未能解决你的问题,请参考以下文章

将 kwargs 传递给 Django 过滤器

argparse - 如何使用 kwargs 或 argv 传递给方法

“kwargs”如何隐式传递给变量?

我可以将 python **kwargs 从 sub 传递给父类吗?

如何从视图将值传递给 Django Form init 方法?

将kwargs传递给django管理表单