I am learning Python.
I learned about default value and arbitrary arguments.
So, I made my function which has a parameter offering a default value, and another parameter having an arbitrary number of arguments.
def make_pizza(size=15,*toppings):
"""Summerize the pizza that we are about to make."""
print("\nMaking a " + str(size) +
"-inch pizza with the following toppings: ")
for topping in toppings:
print("- " + topping)
make_pizza('onion','shrimp','goda cheese','mushroom' )
make_pizza(17,'ham','extra meat','sweet con','pepperoni')
At the first function call, I wanted to use the default value for the "size" parameter which is "15" and the "*toppings" arbitrary argument.
But, I couldn't figure out how to do this.
Could anyone tell me when I call a function with multiple arguments, how I can use parameters' default values and arbitrary arguments at one function call?
Sorry in advance if you feel uncomfortable with my English(I am not a native.)
Mixing parameters with and without default values can indeed be confusing. Parameters are the names used in the function definition, arguments are the values passed into a call.
When calling, Python will always fill all parameters from positional arguments, including names with default values. size
is just another parameter here, even though it has a default value. You can also use name=value
syntax in a call to assign an argument value to a specific parameter (whether or not they have a default value). But you can't tell Python not to assign something to size
, not with your current function definition, because everything before the *toppings
parameter is always going to be a regular positional parameter.
The *toppings
parameter will only capture any positional arguments after all the other parameters have received values. So 'onion'
is assigned to size
, and the remainder is assigned to *toppings
.
In Python 3, you can make size
a keyword-only parameter, by placing them as name=default
after the *toppings
name, or an empty *
:
def make_pizza(*toppings, size=15):
Now size
can only be set from a call with size=<new value>
keyword argument syntax.
In Python 2, you can only capture such keyword arguments with a **kwargs
catch-all parameter, after which you need to look into that dictionary for your size
:
def make_pizza(*toppings, **kwargs):
size = kwargs.get('size', 15) # set a default if missing
In both cases, you have to remember to explicitly name size
, and put such explicitly named keyword arguments after the positional arguments:
make_pizza('ham', 'extra meat', 'sweet con', 'pepperoni', size=17)
There's a fundamental problem with your approach: It's ambiguous because how do you know if you intended it as size
or as topping
? Python can't do that so you need to find an alternative.
Well, you could simply remove size
from the argument list and interpret the first *toppings
argument as size if it's an integer:
def make_pizza(*toppings):
if toppings and isinstance(toppings[0], int):
size, toppings = toppings[0], toppings[1:]
else:
size = 15
print("\nMaking a {}-inch pizza with the following toppings: ".format(size))
for topping in toppings:
print("- " + topping)
However that will fail for cases where a simple type check isn't possible. Maybe the better approach would be to make toppings
a normal argument and size
an optional argument:
def make_pizza(toppings, size=15):
print("\nMaking a {}-inch pizza with the following toppings: ".format(size))
for topping in toppings:
print("- " + topping)
However then you need to pass in a sequence for toppings
and it changes the order of toppings
and size
but it's probably a lot cleaner.
make_pizza(['onion','shrimp','goda cheese','mushroom'])
make_pizza(['ham','extra meat','sweet con','pepperoni'], 17)
You could also keep the toppings as arbitary positional arguments and make size
a keyword-only parameter with default (Python3-only):
def make_pizza(*toppings, size=15):
print("\nMaking a {}-inch pizza with the following toppings: ".format(size))
for topping in toppings:
print("- " + topping)
make_pizza('onion','shrimp','goda cheese','mushroom')
make_pizza('ham','extra meat','sweet con','pepperoni', size=17)
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