繁体   English   中英

传递具有无效键=值对的kwargs来运行

[英]Pass kwargs with invalid key=value pairs to function

以下代码:

def f(a=1):
    pass

kwargs = {}
kwargs['a'] = 1
kwargs['b'] = 2

f(**kwargs)

(正确)引发异常:

Traceback (most recent call last):
  File "tt.py", line 8, in <module>
    f(**kwargs)
TypeError: f() got an unexpected keyword argument 'b'

有没有办法,使用functools或其他方法来绕过这个并找出函数没有使用哪些参数,以便能够将它们传递给另一个函数? 例如,我可能有另一个功能:

def g(a=None, b=None):
    pass

我想打电话给你,比如说

g(**kwargs)

但是我只想要传递b ,因为a在前一个函数中已经“用完了”。

现在我知道这不是理想的编码,但有些情况下它可以派上用场,而且实际上很容易向用户解释,例如“附加参数将传递给f,任何未传递给f的参数都将被传递给g“。

我有点惊讶你问这个问题,并担心你正在做一些你可能会后悔的事情。

您是否尝试使用相同的字典调用不同的方法来提供所有参数组合? 如果是这样,那么处理这种情况所需的复杂性不应该在被调用的方法中处理,而应该在调用代码中处理,例如通过将kwargs定制到要调用的特定方法:

def f(a=1):
    pass

call_tailored_args(f, kwargs)

辅助函数将实现如下:

import inspect

def tailored_args(f, kwargs):
    relevant_args = {k: v in kwargs if k in inspect.getargspec(f).args}
    f(**relevant_args)

你是这个意思吗?

def g(**kwargs):
    a=kwargs.pop('a',None)    
    b=kwargs.pop('b',None)
    print(a,b)
def f(**kwargs):
    a=kwargs.pop('a',None)
    print(a)
    g(**kwargs)

kwargs = {'a':1,'b':2}

f(**kwargs)
# 1
# (None, 2)

您可以使用装饰器删除额外的kwargs键:

def remove_args(fx):
    def wrap(**kwargs):
        kwargs2 = copy.copy(kwargs)

        ret = None
        done = False

        while not done:
            try:
                ret = fx(**kwargs2)
                done = True
            except TypeError, ex:
                key = re.findall("\'(\w+)\'", ex.message)[0]
                del kwargs2[key]              # Remove offending key
                # print "%s removing %s" % (fx.__name__, key)

        return ret

    return wrap


@remove_args
def f1(a=1):
    return "f1-ret"

@remove_args
def f2(b=1):
    return "f2-ret"

kwargs = {"a": 1, "b": 2, "c": 3}

print f1(**kwargs)
print f2(**kwargs)

暂无
暂无

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

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