简体   繁体   English

将参数作为字典传递给 add_argument

[英]Passing arguments to add_argument as a dictionary

I have a program in Python 3.8 which takes multiple different commands (eg mode ), each of which have a different valid constellation of the same options (ie, one option might be only valid in two commands, another in all of them, etc.) I therefore want to define each option (say --my-arg ) once, as a argument dictionary (eg my_arg ), and then pass it to multiple add_argument calls as appropriate for each command using ** .我在 Python 3.8 中有一个程序,它采用多个不同的命令(例如mode ),每个命令都有相同选项的不同有效星座(即,一个选项可能仅在两个命令中有效,另一个在所有命令中有效,等等。 ) 因此,我想将每个选项(比如--my-arg )定义一次,作为参数字典(例如my_arg ),然后将其传递给使用**每个命令的多个add_argument调用。 But for some reason, the option_strings is being dropped in the call, and I don't know why.但是由于某种原因, option_strings在调用中被丢弃了,我不知道为什么。

Minimum reproducible example:最小可重现示例:

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'])

This is the latter part of the output:这是输出的后半部分:

>>> 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

Note that option_strings is [] , when ['--my-arg'] is expected.请注意,当需要['--my-arg']时, option_strings[]

If instead I replicate the option as a positional argument and remove it from the dictionary, it works:相反,如果我将该选项复制为位置参数并将其从字典中删除,它会起作用:

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'])

Output:输出:

>>> 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')

This is a tolerable fix, I suppose (I guess I could write a function to do this for me...), but I beyond wanting to eliminate duplication, I want to understand what's going on.这是一个可以容忍的修复,我想(我想我可以写一个函数来为我做这件事......),但我不想消除重复,我想了解发生了什么。

Apparently you can't get there from here.显然你不能从这里到达那里。 I am opting to use a helper function:我选择使用辅助函数:

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'])

Output:输出:

>>> 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')

Thanks to those who commented.感谢评论的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM