返回值
函数并不总是必须直接显示其输出。 相反,它可以处理一些数据,然后返回一个值或一组值。 函数返回的值称为返回值。 return 语句从函数内部获取一个值并将其发送回调用该函数的行。 返回值允许您将程序的大部分繁重工作转移到函数中,这可以简化程序的主体。
返回简单的值
让我们看一个接受名字和姓氏并返回格式整齐的全名的函数:
def get_formatted_name(first_name, last_name):
"""Return a full name, neatly formatted."""
full_name = f"{first_name} {last_name}" (1)
return full_name.title() (2)
musician = get_formatted_name('jimi', 'hendrix') (3)
print(musician)
1 | get_formatted_name() 的定义将名字和姓氏作为参数。 该函数将这两个名称组合起来,在它们之间添加一个空格,并将结果赋值给 full_name 。 |
2 | full_name 的值转换为 title case,然后返回给调用行 。 |
3 | 当您调用一个返回值的函数时,您需要提供一个可以将返回值分配给的变量。 在这种情况下,返回值被分配给变量 musician 。 |
输出显示了一个格式整齐的名字,由人名的各个部分组成:
Jimi Hendrix
格式化名称似乎是一项艰巨的工作,而我们本可以写:
print("Jimi Hendrix")
但是,当您考虑使用需要分别存储许多名字和姓氏的大型程序时,这似乎需要做很多工作才能获得格式整齐的名字,函数像 get_formatted_name() 变得非常有用。 您分别存储名字和姓氏,然后在您想要显示全名时调用此函数。
让实参变成可选的
有时使参数可选是有意义的,这样使用该函数的人可以选择仅在需要时提供额外信息。 您可以使用默认值使参数可选。
例如,假设我们想扩展 get_formatted_name() 来处理中间名。 第一次尝试包含中间名可能如下所示:
def get_formatted_name(first_name, middle_name, last_name):
"""Return a full name, neatly formatted."""
full_name = f"{first_name} {middle_name} {last_name}"
return full_name.title()
musician = get_formatted_name('john', 'lee', 'hooker')
print(musician)
此函数在给定名字、中间名和姓氏时起作用。 该函数接受名称的所有三个部分,然后从中构建一个字符串。 该函数在适当的地方添加空格并将全名转换为首字母大写:
John Lee Hooker
但是中间名并不总是需要的,如果您尝试仅使用名字和姓氏来调用它,那么编写的这个函数将不起作用。 为了使中间名可选,我们可以给 middle_name 参数一个空的默认值并忽略该参数,除非用户提供一个值。 为了使 get_formatted_name() 在没有中间名的情况下工作,我们将 middle_name 的默认值设置为空字符串并将其移动到参数列表的末尾:
def get_formatted_name(first_name, last_name, middle_name=''):
"""Return a full name, neatly formatted."""
if middle_name: (1)
full_name = f"{first_name} {middle_name} {last_name}"
else: (2)
full_name = f"{first_name} {last_name}"
return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)
musician = get_formatted_name('john', 'hooker', 'lee') (3)
print(musician)
在此示例中,名称由三个可能的部分构成。 因为总是有名字和姓氏,所以这些参数在函数定义中排在第一位。 中间名是可选的,所以它列在定义的最后,它的默认值是一个空字符串。
1 | 在函数体中,我们检查是否提供了中间名。 Python 将非空字符串解释为 True,因此如果中间名参数在函数调用中,条件测试 if middle_name 的计算结果为 True。 如果提供了中间名,则将名字、中间名和姓氏组合起来形成一个全名。 然后将此名称更改为标题大小写并返回到函数调用行,在那里它被分配给变量 musician 并打印出来。 |
2 | 如果没有提供中间名,则空字符串将无法通过 if 测试,并且运行 else 块。 全名仅由名字和姓氏构成,格式化后的名称将返回到调用行,并在调用行中分配给音乐家并打印出来。 |
3 | 使用名字和姓氏调用此函数非常简单。 但是,如果我们使用中间名,我们必须确保中间名是最后传递的参数,这样 Python 才能正确匹配位置参数。 |
我们函数的这个修改版本适用于只有名字和姓氏的人,它也适用于有中间名的人:
Jimi Hendrix
John Lee Hooker
可选值允许函数处理广泛的用例,同时让函数调用尽可能简单。
返回字典
函数可以返回您需要的任何类型的值,包括更复杂的数据结构,如列表和字典。 例如,以下函数接受姓名的一部分并返回表示人的字典:
def build_person(first_name, last_name):
"""Return a dictionary of information about a person."""
person = {'first': first_name, 'last': last_name} (1)
return person (2)
musician = build_person('jimi', 'hendrix')
print(musician) (3)
1 | 函数 build_person() 接受名字和姓氏,并将这些值放入字典。 first_name 的值存储在键“first”中,last_name 的值存储在键“last”中。 |
2 | 然后,返回表示该人的整个字典。 |
3 | 返回值被打印出来,原始的两条文本信息现在存储在字典中:
|
此函数接收简单的文本信息并将其放入更有意义的数据结构中,使您可以处理信息而不仅仅是打印它。 字符串 'jimi' 和 'hendrix' 现在被标记为名字和姓氏。 您可以轻松地扩展此函数以接受可选值,例如中间名、年龄、职业或您想要存储的关于某个人的任何其他信息。 例如,以下更改还允许您存储一个人的年龄:
def build_person(first_name, last_name, age=None):
"""Return a dictionary of information about a person."""
person = {'first': first_name, 'last': last_name}
if age:
person['age'] = age
return person
musician = build_person('jimi', 'hendrix', age=27)
print(musician)
我们在函数定义中添加一个新的可选参数 age,并为该参数分配特殊值 None,当变量没有分配特定值时使用该值。 您可以将 None 视为占位符值。 在条件测试中,None 的计算结果为 False。 如果函数调用包含年龄值,则该值存储在字典中。 这个函数总是存储一个人的名字,但也可以修改它来存储你想要的关于一个人的任何其他信息。
结合使用函数和while循环
到目前为止,您可以使用具有所有 Python 结构的函数。 例如,让我们使用带有 while 循环的 get_formatted_name() 函数来更正式地问候用户。 这是第一次尝试使用他们的名字和姓氏来问候人们:
def get_formatted_name(first_name, last_name):
"""Return a full name, neatly formatted."""
full_name = f"{first_name} {last_name}"
return full_name.title()
# This is an infinite loop!
while True:
print("\nPlease tell me your name:") (1)
f_name = input("First name: ")
l_name = input("Last name: ")
formatted_name = get_formatted_name(f_name, l_name)
print(f"\nHello, {formatted_name}!")
1 | 对于此示例,我们使用不涉及中间名的简单版本的 get_formatted_name()。 while 循环要求用户输入他们的名字,我们分别提示输入他们的名字和姓氏。 |
但是这个 while 循环有一个问题:我们没有定义退出条件。 当你要求一系列输入时,你把退出条件放在哪里? 我们希望用户能够尽可能轻松地退出,因此每个提示都应该提供一种退出方式。 break 语句提供了一种在任一提示符下退出循环的直接方法:
def get_formatted_name(first_name, last_name):
"""Return a full name, neatly formatted."""
full_name = f"{first_name} {last_name}"
return full_name.title()
# This is an infinite loop!
while True:
print("\nPlease tell me your name:")
print("(enter 'q' at any time to quit)")
f_name = input("First name: ")
if f_name == 'q':
break
l_name = input("Last name: ")
if l_name == 'q':
break
formatted_name = get_formatted_name(f_name, l_name)
print(f"\nHello, {formatted_name}!")
我们添加一条消息,通知用户如何退出,然后如果用户在任一提示中输入退出值,我们就会跳出循环。 现在程序将继续问候人们,直到有人输入 q 中的任何一个名字:
Please tell me your name:
(enter 'q' at any time to quit)
First name: eric
Last name: matthes
Hello, Eric Matthes!
Please tell me your name:
(enter 'q' at any time to quit)
First name: q