gpt4 book ai didi

python argparse store --foo=bar as args.key ='foo' , args.value ='bar'

转载 作者:行者123 更新时间:2023-11-30 22:56:23 29 4
gpt4 key购买 nike

我想解析一个具有互斥选项组的命令行。通常,我只会使用 --foo bar这将在命名空间中生成 args.foo = 'bar'

但是,由于所有这些选项都是互斥的,并且我对选项名称和传递给选项的参数都感兴趣,并且我有几个需要向下游提供的选项,我会真正喜欢的是回来args.option_name = 'foo', args.option_value = 'bar'在我的命名空间中而不是 args.foo='bar' .

我所做的是:

class KeyAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)
setattr(namespace, self.dest+'_key', option_string)

frob = parser.add_mutually_exclusive_group()
frob.add_argument('--foo', dest='thing', nargs='?', action=KeyAction)
frob.add_argument('--nar', dest='thing', nargs='?', action=KeyAction)

运行时,我的命名空间将如下所示:

Namespace(thing_key='--foo', thing='bar')

--foo=bar被解析。当然,遗憾的是,如果 --foo 或 --nar 从未传入,namespace.thing_key没有定义,所以我必须使用 getattr() .

操作覆盖虽然有效,但似乎并不正确。

我怀疑 argparse 背后的聪明人已经以某种方式正确地实现了这一点,而我只是在文档和我的文档中遗漏了它读取 argparse.py。

最好的、正确的、Pythonic 的方法是什么?子解析器?我正在使用 python 3.5。

所以我最终使用了您两个答案中的数据来构造这个,它处理选项、它的参数,并在初始化时合理地设置所有内容。

非常感谢您的提示、线索和验证。我很惊讶这之前没有出现在 argparse 中并成为标准化的东西。它一个极端情况,但当使用互斥选项时并不是那么极端的情况。

    class ValueAction(argparse.Action):
"""Override to store both the format type as well as the argument"""
# pylint: disable=too-few-public-methods
def __init__(self, option_strings, dest, **kwargs):
self._dest = dest
dest = dest + '_arguments'
container = kwargs.pop('container')
kwargs['action'] = kwargs.pop('subaction')
action_class = container._pop_action_class(kwargs)
if not callable(action_class):
raise ValueError('unknown action "%s"' % (action_class,))
self._action = action_class(option_strings, dest, **kwargs)
super().__init__(option_strings, dest, **kwargs)

def __call__(self, parser, namespace, values, option_string=None):
self._action(parser, namespace, values, option_string)
if isinstance(option_string, str):
while option_string[0] in parser.prefix_chars:
option_string = option_string[1:]
setattr(namespace, self._dest, option_string)

最佳答案

据我了解,您希望能够指定一个复合操作,以便既保存一个命名空间槽中使用的选项名称,又执行某些其他操作的更新。例如,您希望能够编写如下内容:

group = argparse.mutually_exclusive_group()
group.add_argument('--foo', action=StoreOption, subaction='store_true')
group.add_argument('--bar', nargs='?', action=StoreOption, subaction='store')

操作类是StoreOption,但它会调用subaction指定的操作来对Namespace对象执行额外的更新。

我得到的工作代码(经过非常有限的测试)如下所示:

import argparse

class StoreOption(argparse.Action):
def __init__(self, **kwargs):
kwargs['action'] = kwargs.pop('subaction')
container = kwargs.pop('container')

action_class = container._pop_action_class(kwargs)
if not callable(action_class):
raise ValueError('unknown action "%s"' % (action_class,))

kwargs['dest'] = 'thing'
self._action = action_class(**kwargs)
print "_action:", self._action

super(StoreOption, self).__init__(
option_strings= self._action.option_strings,
dest= self._action.dest,
nargs= self._action.nargs,
const= self._action.const,
default= self._action.default,
type= self._action.type,
choices= self._action.choices,
required= self._action.required,
help= self._action.help,
metavar= self._action.metavar)

def __call__(self, parser, namespace, values, option_string=None):
print "got here:", option_string, namespace
setattr(namespace, 'key', option_string)
self._action(parser, namespace, values, option_string)

测试:

parser = argparse.ArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group()
group.add_argument('--foo', container=group, action=StoreOption, subaction='store_true')
group.add_argument('--bar', container=group, nargs=2, action=StoreOption, subaction='store')

print parser.parse_args(['--bar', 'asd', 'qwe'])
-- prints: Namespace(key='--bar', thing=['asd', 'qwe'])

基本上,StoreOption 是一个包装另一个 Action(由 subaction 指定的操作)的 Action。添加参数时,您需要传递 container= 参数,以便它可以构造子操作。此外,还需要对关键字参数进行一些修改,以便为子操作正确设置它们。

同样,这经过了非常有限的测试,因此它可能不适用于所有子操作,但它应该为您指明正确的方向。

关于python argparse store --foo=bar as args.key ='foo' , args.value ='bar',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37018928/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com