问题
Say I have a function defined thus:
def inner_func(spam, eggs):
# code
I then want to call a function like this:
outer_func(spam=45, eggs="blah")
Inside outer_func
I want to be able to call inner_func
with exactly the same parameters that were passed into outer_func
.
This can be achieved by writing outer_func
like this:
def outer_func(spam, eggs):
inner_func(spam, eggs)
However, I'd like to be able to change the arguments inner_func
takes, and change the parameters I pass to outer_func
accordingly, but without having to change anything in outer_func
each time.
Is there a (easy) way to do this? Python 3 please.
回答1:
Looks like you're looking for the *
and **
notations:
def outer_func(*args, **kwargs):
inner_func(*args, **kwargs)
Then you can do outer_func(1, 2, 3, a='x', b='y')
, and outer_func
will call inner_func(1, 2, 3, a='x', b='y')
.
If you only want to allow keyword arguments, drop the *args
.
In a function definition, a parameter marked with *
receives a tuple of all positional arguments that didn't correspond to other declared parameters, and an argument marked with **
receives a dict of all keyword arguments that didn't correspond to other declared parameters.
In a function call, prefixing a sequence (or other iterable) argument with *
unpacks it into separate positional arguments, and prefixing a mapping argument with **
unpacks it into separate keyword arguments.
回答2:
Not entirely sure I'm getting your drift but you may find functools.wraps
interesting:
@functools.wraps(inner_func)
def outer_func(*args, **kwds):
return inner_func(*args, **kwds)
inspect.signature(outer_func)
# <Signature (spam, eggs)>
Explanation: The "star arguments" collect all the not explicitly specified postional (*args) and keyword (**kwds) arguments that were passed. They can also be used to pass these parameters on; or to manipulate them: args
is a tuple and kwds
is a dict.
Since for example parameter spam
will end up either in args
or kwds
depending on how it was passed, manually parsing star args can be tedious. Here the inspect.Signature
class and in particular its .bind
and .bind_partial
methods are useful.
functools.wraps
is a convenience function/decorator that tweaks many special attributes of the decorated function to make it look like the wrapped function. In particular it copies the name, the signature, the doc string and whatever may be in the wrapped functions __dict__
.
This makes wrapper functions much more user friendly.
来源:https://stackoverflow.com/questions/42724242/how-can-i-pass-keyword-arguments-as-parameters-to-a-function