Passing **kwargs received in a wrapper-function definition, to arguments of an enclosed (i.e. wrapped) function call

岁酱吖の 提交于 2020-01-03 18:32:41

问题


Oh dear, I hope I got the title right. :)

How can one pass the **kwargs supplied to a wrapper-function definition, to another (enclosed) function call that it wraps. For example:

def wrapped_func(**kwargs):
   # Do some preparation stuff here.
   func('/path/to/file.csv', comma_separated_key=value_injected_here)
   # Do some other stuff.

So for example, this call:

wrapped_func(error_bad_lines=True, sep=':', skip_footer=0, ...)

Should result in this:

func('/path/to/file.csv', error_bad_lines=True, sep=':', skip_footer=0, ...)

I've tinkered with a variety of approaches over the past couple of hours, but each exposed type-preservation vulnerabilities (for the values). I've not used this particular wrapper pattern before, and was wondering if the community could give some help. Thank you in advance.


回答1:


**kwargs is a dict, meaning you can use the double splat (**) to unpack it as a list of keyword arguments. So your wrapper function could be like this:

def wrapped_func(**kwargs):
   # Do some preparation stuff here.
   func('/path/to/file.csv', **kwargs)
   # Do some other stuff.



回答2:


Why not simply merge the kwargs:

def func(*args, **kwargs):
    print args
    print kwargs


def wrapped_func(**kwargs):
    # Do some preparation stuff here.
    func('/path/to/file.csv', **dict(comma_separated_key='value_injected_here', **kwargs))
    # Do some other stuff.


wrapped_func(error_bad_lines=True, sep=':', skip_footer=0)

# Outputs:
('/path/to/file.csv',)
{'skip_footer': 0, 'error_bad_lines': True, 'comma_separated_key': 'value_injected_here', 'sep': ':'}



回答3:


An easy way to define a very custom wrapper is to define your own class:

class AdditionWrapper:
    def __init__(self, func):
        self.func = func
    def __call__(self, **kwargs):
        return self.func('/path/to/file.csv', **kwargs)

You could also make the path customizable:

class AdditionWrapper:
    _path = '/path/to/file.csv'
    def __init__(self, func):
        self.func = func
    def __call__(self, **kwargs):
        return self.func(self._path, **kwargs)
    def set_path(self, path):
        self._path = path

Use:

@AdditionWrapper
def myfunc(...):
    ...

myfunc.set_path(mypath)



回答4:


Just use the same syntax when you call a function to expand the kwargs dict as keyword arguments:

func('/path/to/file.csv', **kwargs)

You can also pass in positional arguments in the same way

func('/path/to/file.csv', *args, **kwargs)

Here's a link to the Python docs on the subject: https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists



来源:https://stackoverflow.com/questions/36610950/passing-kwargs-received-in-a-wrapper-function-definition-to-arguments-of-an-e

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!