Is there a Pythonic way to create a function that accepts both separate arguments and a tuple? i.e to achieve something like this:
def f(*args):
"""prints 2 values
f(1,2)
1 2
f( (1,2) )
1 2"""
if len(args) == 1:
if len(args[0]) != 2:
raise Exception("wrong number of arguments")
else:
print args[0][0],args[0][1]
elif len(args) == 2:
print args[0],args[1]
else:
raise Exception("wrong number of arguments")
Example: Pass a Tuple as an Argument using *args Syntax Unpacking in Python uses *args syntax. As functions can take an arbitrary number of arguments, we use the unpacking operator * to unpack the single argument into multiple arguments. This is a special way of receiving parameters to a function as a tuple.
The use of the asterisk * in the call to the function unpacks the tuple and passes its items as positional arguments to the function.
The * symbol is used to pass a variable number of arguments to a function. Typically, this syntax is used to avoid the code failing when we don't know how many arguments will be sent to the function.
First of all I don't know if it is very wise to do so. Say a person calls a function like:
f(*((1,4),(2,5)))
As you can see the tuple contains two elements. But now for some reason, the person calls it with only one element (because for instance the generator did not generated two elements):
f(*((1,4),))
Then the user would likely want your function to report this, but now it will simply accept it (which can lead to complicated and unexpected behavior). Okay printing the elements of course will not do much harm. But in a general case the consequences might be more severe.
Nevertheless an elegant way to do this is making a simple decorator that first checks if one element is fed it checks if one tuple element is feeded and if so expands it:
def one_tuple(f):
def g(*args):
if len(args) == 1 and isinstance(args[0],tuple):
return f(*args[0])
else:
return f(*args)
return g
And apply it to your f
:
@one_tuple
def f(*args):
if len(args) == 2:
print args[0],args[1]
else:
raise Exception("wrong number of arguments")
The decorator one_tuple
thus checks if one tuple is fed, and if so unpacks it for you before passing it to your f
function.
As a result f
does not have to take the tuple case into account: it will always be fed expanded arguments and handle these (of course the opposite could be done as well).
The advantage of defining a decorator is its reuse: you can apply this decorator to all kinds of functions (and thus make it easier to implement these).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With