简体   繁体   English

如何将 **kwargs 参数传递给相关的包装函数?

[英]How to pass **kwargs parameters to the relevant wrapped functions?

I want to define a wrapper function that wraps up a number of other functions with many arguments and want to use the magic variables in the wrapper function.我想定义一个包装器 function,它用许多 arguments 包装许多其他函数,并想使用包装器 function 中的魔法变量。

For example, suppose I have these three functions:例如,假设我有这三个功能:

def function1(ret, ben, period=0, **kwargs):
 return ret, ben, period


def function2(ret, ben, risk_free=0, **kwargs):
 return ret, ben, risk_free

def function3(ret, ben, rf=0, **kwargs):
 return ret, ben, rf

And I want to wrap these functions with another function and use the magic variables so I can keep track of all possible arguments that each function might take.我想用另一个 function 包装这些函数并使用魔术变量,这样我就可以跟踪每个 function 可能采用的所有可能的 arguments。

I have tried something like this:我试过这样的事情:

def wrapper_function(ret, ben, **kwargs):

  out1 = function1(ret, ben, **kwargs)
  out2 = function2(ret, ben, **kwargs)
  out3 = function3(ret, ben, **kwargs)

  return out1, out2, out3 

but this obviously fails because let's say, function1 does not have the same arguments as, for example, function2 .但这显然失败了,因为假设function1与 arguments 不相同,例如function2

For example, if I call the wrapper function with wrapper_function(ret, ben, rf ) it will fail because functions1 and function2 don't have rf as their arguments.例如,如果我使用wrapper_function(ret, ben, rf )调用包装器 function,它将失败,因为functions1function2没有rf作为它们的 arguments。

My scope is essential to have a function that does something like this:我的 scope 对于 function 来说是必不可少的,它可以执行如下操作:

def wrapper_function(ret, ben, **kwargs1,**kwargs2,**kwargs3):

  out1 = function1(ret, ben, **kwargs1)
  out2 = function2(ret, ben, **kwargs2)
  out3 = function3(ret, ben, **kwargs3)

  return out1, out2, out3

This does not seem to work in python, however.但是,这似乎在 python 中不起作用。

Any idea on how to use the magic variable in the wrapper function so no matter what arguments the functions inside it have it would work?关于如何在包装器 function 中使用魔术变量的任何想法,所以无论 arguments 中的函数是什么,它都可以工作吗?

With the help of getfullargspec , You can see what arguments your individual functions need, then get those from kwargs and pass them to the functions.getfullargspec的帮助下,您可以查看 arguments 您的各个函数需要什么,然后从kwargs获取这些并将它们传递给函数。

def wrapper_function(ret, ben, **kwargs):
    fns = (function1, function2, function3)
    results = []

    for fn in fns:
        fn_args = set(getfullargspec(fn).args)
        fn_required_args = fn_args - {'ret', 'ben'}

        required_dict = {
            item: kwargs[item] for item in fn_required_args if item in kwargs
        }
        results.append(fn(ret, ben, **required_dict))

    return results

Here is a complete code for test:下面是完整的测试代码:

from inspect import getfullargspec


def function1(ret, ben, period=0):
    return ret, ben, period


def function2(ret, ben, risk_free=0):
    return ret, ben, risk_free


def function3(ret, ben, rf=0):
    return ret, ben, rf


def wrapper_function(ret, ben, **kwargs):
    fns = (function1, function2, function3)
    results = []

    for fn in fns:
        fn_args = set(getfullargspec(fn).args)
        fn_required_args = fn_args - {'ret', 'ben'}

        required_dict = {
            item: kwargs[item] for item in fn_required_args if item in kwargs
        }
        results.append(fn(ret, ben, **required_dict))

    return results


print(wrapper_function(10, 20, period=11, risk_free=22))

output: output:

[(10, 20, 11), (10, 20, 22), (10, 20, 0)]

note : If you don't want to hardcode this:注意:如果您不想对此进行硬编码:

fn_required_args = fn_args - {'ret', 'ben'}

You can get the {'ret', 'ben'} part, from this expression:您可以从此表达式中获取{'ret', 'ben'}部分:

set(getfullargspec(wrapper_function).args)

Actually, there is a way via introspection (the inspect module).实际上,有一种方法可以通过内省( inspect模块)。 Rough sketch below:草图如下:

import inspect

def wrapper(ret, ben, **kwargs):
    fun1_argnames = inspect.getargspec(function1).args  # get valid args for function1
    theargs = {key: kwargs[key] for key in fun1_argnames}
    function1(**theargs)

However, this is getting a bit into 'hack' territory.然而,这有点进入“黑客”领域。 I have never needed such a trick.我从来不需要这样的把戏。 I have a feeling that your problem could probably be solved in a different way (ie do you really need to wrap a huge amount of different functions with a huge amount of different arguments?)我觉得您的问题可能可以用不同的方式解决(即您真的需要用大量不同的 arguments 包装大量不同的函数吗?)

If I understand the question correctly, you can just pick the relevant arguments out from the kwargs dict:如果我正确理解了这个问题,你可以从kwargs字典中选择相关的 arguments :

def wrapper_function(ret, ben, **kwargs):

    out1 = function1(ret, ben, kwargs['period'])
    out2 = function2(ret, ben, kwargs['risk_free'])

Of course, you may want to first check if they actually exist in the kwargs , eg当然,您可能想先检查它们是否确实存在于kwargs中,例如

period = kwargs['period'] if 'period' in kwargs else 0

This may be useful:这可能有用:

function1(ret, ben, kwargs.get('period'))
...

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

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