将参数作为字典传递给 add_argument

Posted

技术标签:

【中文标题】将参数作为字典传递给 add_argument【英文标题】:Passing arguments to add_argument as a dictionary 【发布时间】:2021-12-14 13:52:45 【问题描述】:

我有一个 Python 3.8 程序,它接受多个不同的命令(例如mode),每个命令都有不同的相同选项的有效星座(即,一个选项可能只在两个命令中有效,另一个在所有命令中有效)其中等)因此我想将每个选项(比如--my-arg)定义一次,作为参数字典(例如my_arg),然后使用@987654326将其传递给适合每个命令的多个add_argument调用@。但由于某种原因,option_strings 在通话中被挂断了,我不知道为什么。

最小可重现示例:

import argparse
parser = argparse.ArgumentParser('Test keyword arguments')
arg_parser = parser.add_subparsers(dest='what_to_run')
parser_mode = arg_parser.add_parser('mode')
my_arg = 'option_strings': ['--my-arg'], 'dest': 'my_arg',
             'help': 'My string argument goes here'
parser_mode.add_argument(**my_arg)
parser.parse_args(['mode', '--my-arg', 'my value'])

这是输出的后半部分:

>>> parser_mode.add_argument(**my_arg)
_StoreAction(option_strings=[], dest='my_arg', nargs=None, const=None, default=None, type=None, choices=None, help='My string argument goes here', metavar=None)
>>> parser.parse_args(['mode', '--my-arg', 'my value'])
usage: Test keyword arguments [-h] mode ...
Test keyword arguments: error: unrecognized arguments: --my-arg

请注意,option_strings[],而应为 ['--my-arg']

如果我将选项复制为位置参数并将其从字典中删除,它会起作用:

import argparse
parser = argparse.ArgumentParser('Test keyword arguments')
arg_parser = parser.add_subparsers(dest='what_to_run')
parser_mode = arg_parser.add_parser('mode')
my_arg = 'dest': 'my_arg', 'help': 'My string argument goes here'
parser_mode.add_argument('--my-arg', **my_arg)
parser.parse_args(['mode', '--my-arg', 'my value'])

输出:

>>> parser_mode.add_argument('--my-arg', **my_arg)
_StoreAction(option_strings=['--my-arg'], dest='my_arg', nargs=None, const=None, default=None, type=None, choices=None, help='My string argument goes here', metavar=None)
>>> parser.parse_args(['mode', '--my-arg', 'my value'])
Namespace(my_arg='my value', what_to_run='mode')

我想这是一个可以容忍的修复(我想我可以编写一个函数来为我做这件事......),但我除了想消除重复之外,我还想了解发生了什么。

【问题讨论】:

因为它是位置参数,而不是关键字参数。 add_argument 没有名为 option_strings 的参数。 你能澄清一下究竟是什么让你感到困惑吗?您需要将 CLI arg 作为位置传递 - **my_arg 不会(不能!)这样做。 好的——很有趣。它接受关键字'option_strings';如果我使用“名称”或“标志”之类的内容,当我调用 add_argument 时会出现错误。 _StoreAction 确实有一个名为 option_strings 的关键字参数。你传递的值在这里被删除:github.com/python/cpython/blob/…. @jonrsharpe Niiii​​ice。感谢您为我找到它。 【参考方案1】:

显然你不能从这里到达那里。我选择使用辅助函数:

import argparse
def add_argument(parser, kwargs):
    return parser.add_argument(*(kwargs['option_strings']), **kwargs)

parser = argparse.ArgumentParser('Test keyword arguments')
arg_parser = parser.add_subparsers(dest='what_to_run')
parser_mode = arg_parser.add_parser('mode')
my_arg = 'option_strings': ['--my-arg'], 'dest': 'my_arg',
             'help': 'My string argument goes here'
add_argument(parser_mode, my_arg)
parser.parse_args(['mode', '--my-arg', 'my value'])

输出:

>>> add_argument(parser_mode, my_arg)
_StoreAction(option_strings=['--my-arg'], dest='my_arg', nargs=None, const=None, default=None, type=None, choices=None, help='My string argument goes here', metavar=None)
>>> parser.parse_args(['mode', '--my-arg', 'my value'])
Namespace(my_arg='my value', what_to_run='mode')

感谢评论的人。

【讨论】:

以上是关于将参数作为字典传递给 add_argument的主要内容,如果未能解决你的问题,请参考以下文章

无法以 GET 类型的方法将字典作为参数传递给 WCF REST 服务

如何将字典传递给带有关键字参数的函数?

将大量参数传递给 Python 函数的方法

将字典传递给 FxCop GUI

Python最小化函数:将附加参数传递给约束字典

通过 add_job_flow_steps 将嵌套字典传递给 EMR