Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 修改后将*args、**kwargs传递给父类_Python - Fatal编程技术网

Python 修改后将*args、**kwargs传递给父类

Python 修改后将*args、**kwargs传递给父类,python,Python,基于a,我实现了以下修改的argparse.Action,它生成键值对 我想允许动态设置nargs,并提供选项,在键可能出现多次的情况下使用defaultdict(list) 以下是我的实施方案: import argparse from collections import defaultdict class NamespaceAction(argparse.Action): """ This modified action allows me to group togeth

基于a,我实现了以下修改的
argparse.Action
,它生成键值对

我想允许动态设置
nargs
,并提供选项,在键可能出现多次的情况下使用
defaultdict(list)

以下是我的实施方案:

import argparse
from collections import defaultdict

class NamespaceAction(argparse.Action):
    """
    This modified action allows me to group together key-value pairs passed to an argument.
    Extended to produce a defaultdict(list) if requested, so that a key can appear more than once.
    """
    def __init__(self, *args, **kwargs):
        self.nargs = kwargs.get('nargs', 1)
        self.mode = kwargs.get('mode', 'dict')  # default mode is dict
        super(NamespaceAction, self).__init__(*args, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        # The default value is often set to None rather than an empty list.
        current_arg_vals = getattr(namespace, self.dest, []) or []
        setattr(namespace, self.dest, current_arg_vals)
        arg_vals = getattr(namespace, self.dest)
        try:
            if self.mode == 'dict':
                arg_vals.append(argparse.Namespace(**dict(v.split('=') for v in values)))
            elif self.mode == 'defaultdict':
                d = defaultdict(list)
                for v in values:
                    v = v.split('=')
                    d[v[0]].append(v[1])
                arg_vals.append(argparse.Namespace(**d))
            else:
                raise NotImplementedError("only dict or defaultdict")
        except TypeError:
            raise RuntimeError('Group {} appears to be incorrectly formatted'.format(values))
但是,使用此选项会导致
TypeError:\uuuu init\uuuu()获得意外的关键字参数“mode”
。但是,如果我从args/kwargs中删除
模式
dict
,它仍然不起作用:

def __init__(self, *args, **kwargs):
    self.nargs = kwargs.get('nargs', 1)
    self.mode = kwargs.get('mode', 'dict')  # default mode is dict
    if 'mode' in kwargs:
        del kwargs['mode']
    if 'nargs' in kwargs:
        del kwargs['nargs']
    super(NamespaceAction, self).__init__(*args, **kwargs)
导致
TypeError:\uuuu init\uuuu()至少接受3个参数(给定1个)


我如何让这个类接受参数,并且仍然正确地初始化父类?

您希望
nargs
具有位置性,但它是一个可选参数;根据文件:

Action类必须接受两个位置参数加上传递给
ArgumentParser的任何关键字参数。除了
Action
本身之外,添加_argument()

您可以尝试:

def __init__(self, *args, **kwargs):
    # To force nargs, look it up, but don't bother setting on self;
    # just let it pass to the parent, if you remove it from kwargs, the
    # parent __init__ overwrites self.nargs with None
    nargs = kwargs['nargs'] 
    assert isinstance(nargs, int) or nargs == "+"
    # dict.pop is like get, but removes the mapping if it exists
    self.mode = kwargs.pop('mode', 'dict')  # Will use 'dict' as default

    # Pass along remaining arguments
    super(NamespaceAction, self).__init__(*args, **kwargs)

考虑到
操作。\uuuuu init\uuuu
采用两个位置参数,
option\u strings
dest
,假设
NamespaceAction
的第一个位置参数是参数数似乎是个坏主意,如果不是错误的话。True,我可以将其更改为另一个关键字参数。这仍然会导致错误
TypeError:\uuu init\uuuu()至少接受3个参数(给定1个)
。不过,我用错了。我需要在
add_argument
中使用kwargs,而不是
action=NamespaceAction()
@IanFiddes:您确定吗?我不能复制。我确实看到了一个缺陷(您正在拦截
nargs
参数,因此对象的
repr
表示它是
None
,即使传递时也是如此,因为parent
\uuuuuu init\uuuuu
上的默认参数会覆盖它;您可以忽略
nargs
,让父类
\uuuu init\uuu
处理它,然后检查以确保
self。nargs
之后是非
None
),但在我使用
解析器时,它可以正常工作。添加_参数('foo',action=NamespaceAction,nargs=12)
,这是调用
NamespaceAction.\uuuu init\uuuu
的地方。回溯是否显示代码的
\uuuu init\uuuuu
有问题?@IanFiddes:是的,应该是
action=NamespaceAction
,没有参数。很高兴你找到了。