Reputation: 17
I am trying to understand how None
as the default parameter works. I have a function that has 4 parameters, first is non-default followed by 3 parameters that are set =None
.
Function: send(name, website=None, to_email=None, verbose=False)
Calling the function: response = send(name, to_email=email, verbose=True)
My question is when calling the function if I remove the "to_email="
and leave it as just email
, an error occurs saying that to_email
is None
. Doesn't it know that email is passed for to_email
parameter (as it's the second parameter I pass)? Why do I have to explicitly say email_to=email
when the parameter email_to=None
?
This is my code that works:
def send(name, website=None, to_email=None, verbose=False):
assert to_email != None
if website != None:
msg = format_msg(my_name=name, my_website=website)
else:
msg = format_msg(my_name=name)
if verbose:
print(name, website, to_email)
# send the message
send_mail(text=msg, to_emails=[to_email], html=None)
if __name__ == "__main__":
print(sys.argv)
name = "Unknown"
if len(sys.argv) > 1:
name = sys.argv[1]
email = None
if len(sys.argv) > 2:
email = sys.argv[2]
response = send(name, to_email=email, verbose=True)
print(response)
Upvotes: 0
Views: 1458
Reputation: 781004
Unnamed arguments are assigned to parameters in the order that they appear in the function definition. So if you write
send(name, email, verbose=True)
the email
argument is assigned to the website
parameter, since that's the second parameter in the function definition. The to_email
parameter gets its default value None
.
If you want to skip any parameters, you have to use named arguments for the rest.
If you want to be able to call it the way you're trying, you need to reorder the parameters:
def send(name, to_email=None, website=None, verbose=False):
Now to_email
is the second parameter.
Upvotes: 1