簡體   English   中英

如何將 **kwargs 參數傳遞給相關的包裝函數?

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

我想定義一個包裝器 function,它用許多 arguments 包裝許多其他函數,並想使用包裝器 function 中的魔法變量。

例如,假設我有這三個功能:

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

我想用另一個 function 包裝這些函數並使用魔術變量,這樣我就可以跟蹤每個 function 可能采用的所有可能的 arguments。

我試過這樣的事情:

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與 arguments 不相同,例如function2

例如,如果我使用wrapper_function(ret, ben, rf )調用包裝器 function,它將失敗,因為functions1function2沒有rf作為它們的 arguments。

我的 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

但是,這似乎在 python 中不起作用。

關於如何在包裝器 function 中使用魔術變量的任何想法,所以無論 arguments 中的函數是什么,它都可以工作嗎?

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

下面是完整的測試代碼:

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:

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

注意:如果您不想對此進行硬編碼:

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

您可以從此表達式中獲取{'ret', 'ben'}部分:

set(getfullargspec(wrapper_function).args)

實際上,有一種方法可以通過內省( 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)

然而,這有點進入“黑客”領域。 我從來不需要這樣的把戲。 我覺得您的問題可能可以用不同的方式解決(即您真的需要用大量不同的 arguments 包裝大量不同的函數嗎?)

如果我正確理解了這個問題,你可以從kwargs字典中選擇相關的 arguments :

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

這可能有用:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM