Make a Python function that returns the same arguments as it receives

Viewed 649

What is a proper way in Python to write a function that will return the very same parameters it received at run-time?

E.g.:

def pass_thru(*args, **kwargs):
    # do something non-destructive with *args & **kwargs
    return ??? <- somehow return *args & **kwargs
2 Answers

Consider the following function:

def a(*args, **kwargs):
    return args, kwargs

When we call the function, the value returned is a tuple, containing first another tuple with the arguments, then a dictionary with the keyword arguments:

b = a(1, 2, 3, a='foo')
print(b)

Outputs: ((1, 2, 3), {'a': 'foo'})

print(b[0]) # Gives the args as a tuple
print(b[1]) # Gives the kwargs as a dictionary

The problem is that your arguments are just a sequence of values, not a value itself you can manipulate. Keyword arguments are not themselves first-class values (that is, a=3 is not a value); they are purely a syntactic construct.

* and ** parameters get you halfway there:

def pass_thru(*args, **kwargs):
    return *args, kwargs

Then

>>> pass_thru(1, 2, a=3)
(1, 2, {'a': 3})

but you can't simply pass that back to pass_thru; you'll get a different result.

>>> pass_thru(pass_thru(1,2,a=3))
((1, 2, {'a': 3}), {})

You can try unpacking the tuple:

>>> pass_thru(*pass_thru(1,2,a=3))
(1, 2, {'a': 3}, {})

but what you really need is to unpack the dict as well. Something like

>>> *a, kw = pass_thru(1,2,a=3)
>>> pass_thru(*a, **kw)
(1, 2, {'a': 3})

As far as I know, there is no way to combine the last example into a single, nested function call.

Related