问题
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