如何将 **kwargs 参数传递给相关的包装函数?
How to pass **kwargs parameters to the relevant wrapped 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
我想用另一个函数包装这些函数并使用魔术变量,这样我就可以跟踪每个函数可能采用的所有可能参数。
我试过这样的方法:
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
但这显然失败了,因为假设 function1
没有相同的参数,例如 function2
.
例如,如果我用 wrapper_function(ret, ben, rf )
调用包装函数,它将失败,因为 functions1
和 function2
没有 rf
作为它们的参数。
我的示波器对于具有执行以下操作的功能至关重要:
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
然而,这在 python 中似乎不起作用。
知道如何在包装函数中使用魔法变量,这样无论函数内部的参数是什么,它都可以工作吗?
这可能有用:
function1(ret, ben, kwargs.get('period'))
...
如果我理解正确的话,你可以从kwargs
dict中挑选出相关的参数:
def wrapper_function(ret, ben, **kwargs):
out1 = function1(ret, ben, kwargs['period'])
out2 = function2(ret, ben, kwargs['risk_free'])
当然,您可能想先检查它们是否确实存在于kwargs
中,例如
period = kwargs['period'] if 'period' in kwargs else 0
实际上,有一种方法是通过内省(inspect
模块)。草图如下:
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)
但是,这有点进入 'hack' 领域。我从来不需要这样的把戏。我觉得您的问题可能可以用不同的方式解决(即您真的需要用大量不同的参数包装大量不同的函数吗?)
在 getfullargspec
的帮助下,您可以查看您的各个函数需要哪些参数,然后从 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
完整的测试代码如下:
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))
输出:
[(10, 20, 11), (10, 20, 22), (10, 20, 0)]
注意:如果你不想硬编码:
fn_required_args = fn_args - {'ret', 'ben'}
你可以从这个表达式中得到 {'ret', 'ben'}
部分:
set(getfullargspec(wrapper_function).args)
我想定义一个包装函数,它用许多参数包装许多其他函数,并想在包装函数中使用魔法变量。
例如,假设我有这三个函数:
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
我想用另一个函数包装这些函数并使用魔术变量,这样我就可以跟踪每个函数可能采用的所有可能参数。
我试过这样的方法:
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
但这显然失败了,因为假设 function1
没有相同的参数,例如 function2
.
例如,如果我用 wrapper_function(ret, ben, rf )
调用包装函数,它将失败,因为 functions1
和 function2
没有 rf
作为它们的参数。
我的示波器对于具有执行以下操作的功能至关重要:
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
然而,这在 python 中似乎不起作用。
知道如何在包装函数中使用魔法变量,这样无论函数内部的参数是什么,它都可以工作吗?
这可能有用:
function1(ret, ben, kwargs.get('period'))
...
如果我理解正确的话,你可以从kwargs
dict中挑选出相关的参数:
def wrapper_function(ret, ben, **kwargs):
out1 = function1(ret, ben, kwargs['period'])
out2 = function2(ret, ben, kwargs['risk_free'])
当然,您可能想先检查它们是否确实存在于kwargs
中,例如
period = kwargs['period'] if 'period' in kwargs else 0
实际上,有一种方法是通过内省(inspect
模块)。草图如下:
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)
但是,这有点进入 'hack' 领域。我从来不需要这样的把戏。我觉得您的问题可能可以用不同的方式解决(即您真的需要用大量不同的参数包装大量不同的函数吗?)
在 getfullargspec
的帮助下,您可以查看您的各个函数需要哪些参数,然后从 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
完整的测试代码如下:
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))
输出:
[(10, 20, 11), (10, 20, 22), (10, 20, 0)]
注意:如果你不想硬编码:
fn_required_args = fn_args - {'ret', 'ben'}
你可以从这个表达式中得到 {'ret', 'ben'}
部分:
set(getfullargspec(wrapper_function).args)