免费的清晰思维导图见上传资源压缩包,也不需要积分。
目录
2.3.1 *formal_parameter:将接受的所有实参封装进空元组
2.3.3 **formal_parameter:使用任意数量的关键字实参(空字典,可接受任意数量的键-值对)
函数是带名字的代码块,用于完成具体的工作,要执行函数定义的特定任务,可调用该函数。
使用函数可以让你的程序更容易扩展和维护,与必须修改多个地方相比,使用函数修改的效率更高。通过使用函数,程序的编写、阅读、测试和修复都将更容易。
本章的最后还会学习如何将函数存储在被称为模块的独立文件中,让主程序文件的组织更为有序。
1 定义函数
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数(不需要输入时括号内为空)。
- 函数的第一行语句可以选择性地使用文档字符串(docstring)—用于存放函数说明,文档字符串用三引号括起,如"""注释"""。
- 函数内容以冒号 : 起始,并且缩进,称为函数体。
- return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
def function(formal parameter):
"""docstring"""
function body
def 函数名(形参):
"""文档字符串注释"""
函数体
2 传递信息
2.1 基础知识:形参与实参
(1)在函数定义def function_name()的括号内添加形参,通过添加形参可以让函数接受输入给它的任何值。
(2)形参是一个变量,用于函数完成其工作所需的一项信息。
(3)实参是一个值,调用函数时传递给函数的信息。
(4)在调用函数时,将要让函数使用的信息放在括号内。
(5)调用函数时,将实参的值传递给了函数,这个值被存储在形参这个变量中。
#定义一个函数
def function(formal parameter):
"""docstring"""
function body
#调用该函数
function(actual parameter)
def 函数名称(形参):
"""文档字符串注释"""
函数体
函数名称(实参)
2.2 传递实参
函数定义中可以包含多个形参,也可以包含多个实参。
(1)调用函数时,必须将函数调用中的每个实参都关联到函数定义中的一个形参。
(2)方法概述
方法 | 使用要求 |
位置实参 | 要求实参的顺序与形参的顺序相同 |
关键字实参 | 每个实参都由变量名和值组成 |
列表 | |
字典 |
2.2.1 位置实参
位置实参基于实参的顺序将实参和形参相关联。
def function(formal parameter_01,formal parameter_02):
"""docstring"""
function body
function(actual parameter_01,actual parameter_02)
function(actual parameter_03,actual parameter_04)
(1)在函数中,可根据需要使用任意数量的位置实参,Python将按顺序将函数调用中的实参关联到函数定义中相应的形参。
(2)调用函数多次是一种效率极高的工作方式,你可以多次调用一个函数。
(3)**在使用位置实参来调用函数时,要确保函数调用中实参的顺序和函数定义中形参的顺序一致。
2.2.2 关键字实参
关键字实参关键字实参是传递给函数的名称-值对,直接在实参中将名称和值关联起来了。
def function(formal parameter_01,formal parameter_02):
"""docstring"""
function body
function(formal parameter_01=actual parameter_01,formal parameter_02=actual parameter_02)
或
function(formal parameter_02=actual parameter_02,formal parameter_01=actual parameter_01)
(1)关键字实参无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。
(2)关键字实参的顺序无关紧要,但是要准确指定函数定义中的形参名称。
2.2.3 默认值
编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,程序将使用指定实参值;否则将使用形参的默认值。
使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参。(在使用位置实参时这点非常重要)
即:def 函数名称(形参1,形参2,形参3=默认值,形参4=默认值,形参5=默认值)
不能将形参3、4、5这样有默认值的形参放在前面,因为当你使用位置实参时,就算前面的形参是已经设置默认值(并且就打算使用默认值的),也会被第一个实参给赋值覆盖掉。
#在定义函数时,有默认值的形参要放在形参列表后面
def function(formal parameter_01,formal parameter_02=value)
"""docstring"""
function body
#不改变默认值
#使用位置实参
function(value_01)
#使用关键字实参
function(formal parameter_01=value_01)
#显示提供formal parameter_02的值,覆盖默认值value
#使用位置实参
function(value_01,value_02)
#使用关键字实参
function(formal parameter_01=value_01,formal parameter_02=value_02)
或
function(formal parameter_02=value_02,formal parameter_01=value_01)
(1)在使用默认值时,调用函数不需要再给该形参提供值。
(2)在不使用该默认值时,需显式向该形参提供实参,Python将忽略这个形参的默认值。
(3)定义函数时,有无使用默认值,都可以使用位置实参。
(4)以上四种函数调用称为等效的函数调用,输出都是一样的。
2.2.4 实参错误
实参错误提供的实参多于或少于函数完成其工作所需的信息时,将出现实参不怕匹配错误。
Traceback(most recent call last):
File "*.py",line ,in<*>
function_name()
TypeError:function_name() missing * required positional arguments:'*' and '*'
2.3 传递任意数量的实参
假设你预先不知道函数需要接受多少实参,Python允许函数从调用语句中收集任意数量的实参。
**使用方法概述:
表示方法 | 创建内容 | 使用要求 |
*formal_parameter | 空元组 | 已知输入类型,未知输入具体数目 |
**formal_parameter | 空字典 | 未知输入类型,未知输入具体数目 |
2.3.1 *formal_parameter:将接受的所有实参封装进空元组
使用空元组:*formal_parameter创建一个空元组,并将收到的所有值都封装在该元组中,即便只收到一个值也如此。
示例:创建一个制作比萨的函数,它需要接受很多配料,但你无法预先确定顾客要多少种配料,故调用形参*toppings。
#pizza.py def make_pizza(*toppings): """打印顾客点的所有配料""" print(toppings) make_pizza('pepperoni') make_pizza('mushrooms','green peppers','extra cheese') >>('pepperoni',) ('mushrooms', 'green peppers', 'extra cheese') #向函数make_pizza中加入一个for循环来遍历列表 def make_pizza(*toppings): """概述要制作的比萨""" print("\nMaking a pizza with the following toppings:") for topping in toppings: print("- " + topping) make_pizza('pepperoni') make_pizza('mushrooms','green peppers','extra cheese') >>Making a pizza with the following toppings: - pepperoni Making a pizza with the following toppings: - mushrooms - green peppers - extra cheese
如此可见,*formal_parameter无论接受多少实参,1个或是多个,都会将其封装在一个元组中。即无论函数接受多少实参,这种语法都管用。
2.3.2 结合使用位置实参和任意数量实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
def function(formal_parameter_01,*formal_parameter_02):
"""docstring"""
print(formal_parameter_01)
for value in formal_parameter_02:
print(value)
function(actual_parameter_01,actual_parameter_02)
function(actual_parameter_01,actual_parameter_02,actual_parameter_03,actual_parameter_04)
示例:
def make_pizza(size,*toppings): """概述要制作的比萨""" print("\nMaking a " + str(size) + "-inch pizza with the following toppings:") for topping in toppings: print("- " + topping) make_pizza(16,'pepperoni') make_pizza(12,'mushrooms','green peppers','extra cheese') >>Making a 16-inch pizza with the following toppings: - pepperoni Making a 12-inch pizza with the following toppings: - mushrooms - green peppers - extra cheese
2.3.3 **formal_parameter:使用任意数量的关键字实参(空字典,可接受任意数量的键-值对)
需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键值对(以关键字实参的方式输入)——调用语句提供了多少就接受多少。
(1)使用空字典:**formal_parameter创建一个空字典,接受任意数量的关键字实参,将收到的所有名称-值对都封装到这个字典中。
(2)在这个函数中,可以像访问其他字典那样访问所返回字典的名称-值对。
(3)编写函数时,可以以各种方式混合使用位置实参、 关键字实参和任意数量的实参。
示例:
def build_profile(first,last,**user_info): """创建一个字典,其中包含我们知道的有关客户的一切""" profile = {} profile['first_name'] = first profile['last_name'] = last for key,value in user_info.items(): profile[key] = value return profile user_profile = build_profile('albert','einstein', location = 'princeton', field = 'physics') print(user_profile)
2.4 传递列表
2.4.1 传递简单的列表
将列表传递给函数时,函数可以直接访问其内容。这种列表包含的可以是名字、数字或是更复杂的对象(如字典)。
def function(formal_parameter_list):
"""docstring"""
for value in list:
do something
list=[value_01,value_02,value_03]
function(list)
2.4.2 在函数中修改列表
(1)在函数中对列表所做的任何修改都是永久性的,这便于用户能够高效地大量处理数据。
(2)使用函数对列表进行修改,能让程序更容易维护。
(3)需要注意的是,每个函数都应只负责一项工作,比如处理数据、打印结果等等。
(4)如果某个函数执行的任务太多,应该将其拆分为两个函数。
(5)可以在一个函数中调用另一个函数,这有助于将复杂的任务划分成一系列的步骤。
这里其实就是把函数体改为对列表进行一些处理,和简单列表的抽象结构图没有太大区别,所以这里举一个书上的示例:
假设有一家为用户提交设计制作3D打印模型的公司。需要打印的设计存储在一个列表中,打印后移到另一个列表中,假如其不使用函数。
#首先创建一个列表,其中包含一些要打印的设计 unprinted_designs = ['iphone case','robot pendant','dodecahedron'] completed_models = [] #模拟打印每个设计,直到没有未打印的设计位置 #打印每个设计后,都将其移动到列表completed_models中 while unprinted_designs: current_design = unprinted_designs.pop() #模拟根据设计制作3D打印模型的过程 print("Printing model:" + current_design) completed_models.append(current_design) #显示打印好的所有模型 print("\nThe following models have been printed:") for completed_model in completed_models: print(completed_model)
根据这个代码的结构,我们可以拆分出两个函数模块,一个是处理数据(将元素从未打印列表中弹出,加入到已打印列表中),另一个是打印结果(将已打印列表输出)。
#处理函数 def print_models(unprinted_designs,completed_models): """ 模拟打印每个设计,直到没有未打印的设计为止 打印每个设计后,都将其移到列表completed_models中 """ while unprinted_designs: current_design = unprinted_designs.pop() #模拟根据设计制作3D打印模型的过程 print("Printing model:" + current_design) completed_models.append(current_design) #打印函数 def show_completed_models(completed_models): """显示打印好的所有模型""" print("\nThe following models have been printed:") for completed_model in completed_models: print(completed_model) unprinted_designs = ['iphone case','robot pendant','dodecahedron'] completed_models = [] print_models(unprinted_designs,completed_models) show_completed_models(completed_models)
2.4.3 禁止函数修改列表:函数处理后仍需保留原列表
如果在函数处理后还需要使用原列表,可以向函数传递列表的副本;这样函数所做的任何修改都只影响副本,丝毫不影响原件。
切片表示法[:] : 创建列表的副本
function_name(list_name[:])
示例:print_models(unprinted_design[:],completed_models)
这样函数print_models()依然可以一完成其工作,但是它使用的是unprinted_design的副本,而不是列表本身,不会修改原有列表。
**切片表示法是针对实参输入时使用的,而不是在形参处切片。
虽然传递副本的方式可以保留原列表,但是除了需要使用原列表,否则还是将原始列表传递给函数,因为让函数使用现成列表可以避免花时间和内存创建副本(使用副本会增加程序的时间复杂度和空间复杂度),从而提高效率,在处理大型列表时尤其如此。
3 返回值
3.1 返回简单值
(1)函数并非总是直接显示输出,它也可以处理一些数据,并返回一个或一组值。函数返回的值被称为返回值。
(2)在函数中,可使用return语句将值返回到调用函数的代码行。
(3)调用返回值的函数时,需要提供一个变量,用于存储返回的值。
#定义一个函数
def function(formal parameter_01,formal parameter_02):
"""docstring"""
function body
#该函数返回一个值
return value
#定义一个变量来接受该函数的返回值
variable = function(actual parameter_01,actual parameter_02)
#输出该变量
print(variable)
第一次学习返回值的结构,为了更清晰一点这里举一个书上的示例:
#formatted_name.py def get_formatted_name(first_name,last_name): """返回整洁的姓名""" full_name = first_name + " " + last_name return full_name.title() musician = get_formatted_name('jimi','hendrix') print(musician) >>Jimi Hendrix
在需要分别大量储存名和姓的大型程序中,这样的函数将非常有用,只需要调用该函数而不是每个姓名的输入,会便捷很多。
3.2 创建可选实参
(1)将实参变为可选值,使用函数的人就只需在必要时才提供额外的信息,可使用默认值来让实参变成可选的,例如:给实参指定一个默认值——空字符串,可以搭配if语句在提供该实参和不提供该实参时输出不同内容。
#定义一个函数
#这里实参3的引号里是不加空格的
def function(formal parameter_01,formal parameter_02,formal parameter_03=''):
"""docstring"""
#若该函数输入了实参3,即输入了actual parameter_03覆盖了formal parameter_03的空字符
if formal parameter_03:
do something
#否则
else:
do something
#该函数返回一个值
return value
#定义一个变量来接受该函数的返回值
#调用函数时,如果未输入实参3,形参3将保持默认值的空白
variable_01 = function(actual parameter_01,actual parameter_02)
#若输入实参3,形参3的默认值将被覆盖
variable_02 = function(actual parameter_01,actual parameter_02,actual parameter_03)
#输出该变量
print(variable_01)
print(variable_02)
(2)可选实参(有默认值)要放在末尾定义。
基于3.1的示例优化一下,得到一个3.2的示例:
def get_formatted_name(first_name,last_name,middle_name=''): """返回整洁的姓名""" if middle_name: full_name = first_name + ' ' + middle_name + ' ' + last_name else: full_name = first_name + ' ' + last_name return full_name.title() musician = get_formatted_name('jimi','hendrix') print(musician) musician = get_formatted_name('john','hooker','lee') print(musician) >>Jimi Hendrix John Lee Hooker
3.3 返回字典
(1)函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。
(2)返回字典:函数接受值,并将这些值封装到字典中。
#定义一个函数
def function(formal_parameter_01,formal_parameter_02,formal_parameter_03=''):
"""docstring"""
#将函数接受到的参数封装进字典中
dictionary = {key_01:formal_parameter_01,key_02:formal_parameter_02}
#如果有实参3输入,即覆盖形参3默认值的话
if formal_parameter_03:
dictionary[key_03] = formal_parameter_03
return dictionary
#定义两个变量接受调用函数的返回值
#若只传输两个实参,即形参3使用默认值
variable_01 = function(actual_parameter_01,actual_parameter_02)
#若传输三个实参,即形参3不使用默认值,被覆盖
variable_02 = function(actual_parameter_01,actual_parameter_02,actual_parameter_03)
#输出两个变量
print(variable_01)
print(variable_02)
示例:创建一个函数,将用户输入的个人信息封装在字典中。
def build_person(first_name,last_name,age=''): """返回一个字典,其中包含有关一个人的信息""" person = {'fist':first_name,'last':last_name} if age: person['age'] = age return person musician = build_person('jimi','hendrix') print(musician) musician = build_person('john','lee',22) print(musician) >>{'fist': 'jimi', 'last': 'hendrix'} {'fist': 'john', 'last': 'lee', 'age': 22}
3.4 与while循环结合
函数可以结合任意一种Python结构使用。
#定义一个函数
def function(formal_parameter_01,formal_parameter_02):
"""docstring"""
function body
return value
#执行while循环
while True:
#若用户输入'q'时退出该循环
print("Enter 'q' at any time to quit")
#引导用户输入变量1
variable_01 = input("Enter actual parameter_01:")
if variable_01 == 'q':
break
#引导用户输入变量2
variable_02 = input("Enter actual parameter_02:")
if variable_02 == 'q':
break
#调用函数,将变量1和变量2作为实参传输给函数,使用变量3来接受该函数的返回值
variable_03 = function(variable_01,variable_02)
#输出函数调用的结果
print(variable_03)
示例:依次提示用户输入名和姓,调用get_formatted_name函数将其拼凑为完整的姓名,结合while循环完成多次输入,并打印针对该用户姓名的欢迎语,直到用户输入'q'时退出循环。
def get_formatted_name(first_name,last_name): """返回整洁的姓名""" full_name = first_name + ' ' + last_name return full_name.title() 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("\nHello," + formatted_name + "!")
4 将函数存储在模块中
4.1 使用模块的好处
(1)将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。import语句允许在当前运行的程序文件中使用模块中的代码。
(2)通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在程序的高层逻辑上,可以在众多不同的程序中重用函数,还可以使用其他程序员编写的函数库。
4.1 模块的定义与使用
(1)创建模块:模块是扩展名为.py的文件,包含要导入到程序中的代码。
(2)应用方法概述:
应用方法 | 引用方法 | 调用函数 |
导入整个模块 | import module_name | module_name.function_name() |
导入特定函数 | ①from module_name import function_name ②from module_name import function_0,function_1,function_3 | function_name() |
给函数指定别名 | from module_name import function_name as fn | fn() |
给模块指定别名 | import module_name as mn | mn.function_name() |
导入模块中所有函数 | from module_name import * | function_name() |
4.1.1 导入整个模块
import module_name
module_name.function_name()
只需编写一条import语句并在其中指定模块名,就可在程序中使用该模块中的所有函数。
(1)在程序所在的文件中,新建一个储存函数的文件funtion.py,将这个文件使用import导入刚创建的模块module,再进行调用。
(2)import module_name让Python打开function.py文件,并将其中所有的函数都复制到当前程序中,令用户可使用function.py中所定义的所有函数。
最好使用这种语法以及句点表示法去调用需要使用的函数,能防止有函数或变量名称一样被覆盖。
4.1.2 导入特定的函数
#只从模块中导入某个特定函数
from module_name import function_name
function_name()
#从模块中导入任意数量的函数
from module_name import function_0,function_1,function_2
function_0()
function_1()
function_2()
若使用这种语法,调用函数时就无需使用句点。(由于在import语句中显式地导入了函数,因此调用它时只需指定其名称)
4.1.3 使用as给函数指定别名
#fn为别名、简写
from module_name import function_name as fn
如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名——函数的另一个名称。
4.1.4 使用as给模块指定别名
#mn为模块的别名、简称
import module_name as mn
通过给模块指定简短的别名,可以让用户能够更轻松地调用模块中的函数。
4.1.5 导入模块中的所有函数
from module_name import *
function_name()
使用星号(*)运算符可让Python导入模块中地所有函数。由于导入了每个函数,可以通过名称来调用每个函数,从而无需使用句点表示法。
使用并非自己编写的大型模块时,最好不要采用这种导入方法:
如果模块中有函数的名称与你的项目中使用的名称相同,可能导致意想不到的结果——Python可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有的函数。
5 函数编写指南
(1)给函数、模块命名时需要指定描述性名称,且只在其中使用小写字母和下划线
(2)每个函数都应包含简要注释(描述其功能),该注释应紧跟在函数定义后面,并采用文档字符串格式。
(3)给形参指定默认值时,等号两边不要有空格。
(4)使用关键字形参时,等号两边不要有空格。
(5)有多个形参时,可在函数定义中输入左括号后换行,并在下一行按两次Tab键,从而将形参列表和只缩进一层的函数体区分开来。
形参:2次Tab,8字符缩进
函数体:1次Tab,4字符缩进
def function_name(
parameter_0,parameter_1,parameter_2,
parameter_3,parameter_4,parameter_5):
function body…
(6)若程序或模块中包含多个函数,可使用两个空行将相邻的函数分开,这样将更容易知道前一个函数在什么地方结束,下一个函数从什么地方开始。
(7)所有import语句都应放在文件开头(当开头添加了对整个程序的注释是import语句在注释之后)。
6 课后题
题目在注释里,因为后面有一些是模块调用的代码,所以会分两个代码part。
#课本例题8.1 定义函数
print("\n课本例题8.1")
#greeter.py
#定义函数
def greet_user():
"""显示简单的问候语"""
print("Hello!")
greet_user()
#向函数传递信息
def greet_user(username):
"""显示简单的问候语"""
print("Hello " + username.title() + "!")
greet_user('jesse')
#课后习题8-1 消息:编写一个名为display_message()的函数,它打印一个句子,指出你在本章学的是什么
#调用这个函数,确认显示的消息正确无误
print("\n课后习题8-1")
def display_message():
"""显示本章学的是什么"""
print("函数的定义")
display_message()
#课后习题8-2 喜欢的图书:编写一个名为favorite_book()的函数,其中包含一个名为title的形参
#这个函数打印一条消息,如One of my favorite books is Alice in Wonderland
#调用这个函数,并将一本图书的名称作为实参传递给它
print("\n课后习题8-2")
def favorite_book(title):
"""打印喜欢的图书名称"""
print("One of my favorite books is " + title + ".")
favorite_book('Alice in Wonderland')
#课本例题8.2 传递实参
print("\n课本例题8.2")
#pets.py
#位置实参
def describe_pet(animal_type,pet_name):
"""显示宠物的信息"""
print("I have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('hamster','harry')
#调用函数多次
def describe_pet(animal_type,pet_name):
"""显示宠物的信息"""
print("I have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('hamster','harry')
describe_pet('dog','willie')
#关键字实参
describe_pet(animal_type='hamster',pet_name='harry')
#默认值
def describe_pet(pet_name,animal_type='dog'):
"""显示宠物的信息"""
print("I have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(pet_name='willie')
describe_pet(pet_name='harry',animal_type='hamster')
#课后习题8-3 T恤:编写一个名为make_shirt()的函数,它接受一个尺码以及要印到T恤的字样,这个函数打印一个句子,概要地说明T恤的尺码和字样
print("\n课后习题8-3")
def T_shirt(size,typeface):
"""打印T恤的尺码和T恤上需要打印的字样"""
print("Need " + size.title() + " size T-shirt.")
print("T-shirt with ' " + typeface + " ' printed on it.")
#使用位置实参调用这个函数来制作一件T恤,再使用关键字实参来调用该函数
T_shirt('M','Miss you')
T_shirt(size='M',typeface='Miss you')
#课后习题8-4 大号T恤:修改函数make_shirt(),使其在默认情况下制作一件印有字样“I love Python”的大号T恤
#调用这个函数来制作如下T恤:一件印有默认字样的大号T恤、一件印有默认字样的中号T恤和一件印有其他字样的T恤(尺码无关紧要)
print("\n课后习题8-4")
def make_shirt(size='L',typeface='I love Python'):
"""打印T恤的尺码和T恤上需要打印的字样"""
print(size.title() + " size T-shirt.")
print("T-shirt with ' " + typeface + " ' printed on it.")
make_shirt()
make_shirt(size='M')
make_shirt(size='S',typeface='I love C')
#课后习题8-5 城市:编写一个名为describe_city()的函数,它接受一座城市的名字以及该城市所属的国家
#这个函数应打印一个简单的句子,如Reykjavik is in Iceland
#给用于存储国家的形参指定默认值
#为三座不同的城市调用这个函数,且其中至少有一座城市不属于默认国家
print("\n课后习题8-5")
def describe_city(city_name,country='China'):
"""打印一座城市的名字和它所属的国家"""
print(city_name.title() + " is in " + country.title() + ".")
describe_city(city_name='Beijing')
describe_city(city_name='Shanghai')
describe_city(city_name='Reykjavik',country='Iceland')
#课本例题8.3 返回值
print("\n课本例题8.3")
#返回简单值
#formatted_name.py
def get_formatted_name(first_name,last_name):
"""返回整洁的姓名"""
full_name = first_name + " " + last_name
return full_name.title()
musician = get_formatted_name('jimi','hendrix')
print(musician)
#可选实参
def get_formatted_name(first_name,last_name,middle_name=''):
"""返回整洁的姓名"""
if middle_name:
full_name = first_name + ' ' + middle_name + ' ' + last_name
else:
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_formatted_name('jimi','hendrix')
print(musician)
musician = get_formatted_name('john','hooker','lee')
print(musician)
#返回字典
#person.py
def build_person(first_name,last_name):
"""返回一个字典,其中包含有关一个人的信息"""
person = {'fist':first_name,'last':last_name}
return person
musician = build_person('jimi','hendrix')
print(musician)
#对build_person优化,可以存储年龄
def build_person(first_name,last_name,age=''):
"""返回一个字典,其中包含有关一个人的信息"""
person = {'first':first_name,'last':last_name}
if age:
person['age'] = age
return person
musician = build_person('jimi','hendrix')
print(musician)
musician = build_person('john','lee',22)
print(musician)
#结合使用函数和while循环
#greeter.py
def get_formatted_name(first_name,last_name):
"""返回整洁的姓名"""
full_name = first_name + ' ' + last_name
return full_name.title()
#自己写的while循环,使用了or结构,但是需要将f_name和l_name都输入完,根据两者中是否有一个为quit才能判断是否退出循环
while True:
print("\nPlease tell me your name:")
print("(if you input 'quit',the program will be quit.)")
f_name = input("First name: ")
l_name = input("Last name: ")
if (f_name == 'quit') or (l_name == 'quit'):
break
else:
formatted_name = get_formatted_name(f_name,l_name)
print("\nHello," + formatted_name + "!")
#课本上的while循环,只要f_name和l_name有一个输入q,循环立刻结束
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("\nHello," + formatted_name + "!")
#课后习题8-6 城市名:编写一个名为city_country()的函数,它接受城市名称及其所属的国家
#这个函数应返回一个格式类似于如下的字符串:"Santiago,Chile"
print("\n课后习题8-7")
def city_country(city_name,country):
"""输出城市名称及其所属的国家"""
city_name_country = city_name.title() + "," + country.title()
return city_name_country
c_1 = city_country('Santiago','Chile')
print(c_1)
#课后习题8-7 专辑:编写一个名为make_album()的函数,它创建一个描述音乐专辑的字典
#这个函数应接受歌手的名字和专辑名,并返回一个包含这两项信息的字典
#使用这个函数创建三个表示不同专辑的字典,并打印每个返回值,以核实字典你正确的存储了专辑的信息
print("\n课后习题8-7")
def make_album(singer,album_name):
"""输出歌手和专辑名称"""
album = {'singer':singer,'album name':album_name}
return album
album_info_01 = make_album('singer_01','album_01')
album_info_02 = make_album(singer='singer_02',album_name='album_02')
print(album_info_01)
print(album_info_02)
#给函数make_album()添加一个可选形参,以便能够存储专辑包含的歌曲数目
#如果调用这个函数时指定了歌曲数,就将这个值添加到表示专辑的字典中
#调用这个函数,并至少再一次调用中使用指定专辑包含的歌曲数
def make_album(singer,album_name,song_number=''):
"""记录歌手、专辑名称和歌曲数目"""
album = {'singer':singer,'album name':album_name}
if song_number:
album['song number'] = song_number
return album
album_info_01 = make_album('singer_01','album_01')
album_info_02 = make_album(singer='singer_02',album_name='album_02',song_number=3)
print(album_info_01)
print(album_info_02)
#课后习题8-8 用户的专辑:基于练习8-7的程序,编写一个while循环,让用户输入一个专辑的歌手和名称
#获取这些信息后,使用它们来调用函数make_album(),并将创建的字典打印出来
#在这个while循环中,务必要提供退出途径
print("\n课后习题8-8")
def make_album(singer_name,album_name,song_number=''):
"""记录歌手、专辑名称和歌曲数目"""
album = {'Singer Name':singer_name,'Album Name':album_name}
if song_number:
album['Song Number'] = song_number
return album
while True:
print("\nPlease enter the information about album.")
print("If you enter 'q',the program will be quit.")
singer_name_input = input("Singer Name:")
if singer_name_input == 'q':
break
album_name_input = input("Album Name:")
if album_name_input == 'q':
break
song_number_input = input("Song Number:")
if song_number_input == 'q':
break
album_info = make_album(singer_name_input,album_name_input,song_number_input)
print(album_info)
#课本例题8.4 传递列表
#greet_users.py
def greet_users(names):
"""向列表中的每位用户都发出简单的问候"""
for name in names:
msg = "Hello," + name.title() + "!"
print(msg)
usernames = ['hannah','ty','margot']
greet_users(usernames)
#printing_models.py
#假如该代码不使用函数处理
#首先创建一个列表,其中包含一些要打印的设计
unprinted_designs = ['iphone case','robot pendant','dodecahedron']
completed_models = []
#模拟打印每个设计,直到没有未打印的设计位置
#打印每个设计后,都将其移动到列表completed_models中
while unprinted_designs:
current_design = unprinted_designs.pop()
#模拟根据设计制作3D打印模型的过程
print("Printing model:" + current_design)
completed_models.append(current_design)
#显示打印好的所有模型
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
#使用函数处理
#处理函数
def print_models(unprinted_designs,completed_models):
"""
模拟打印每个设计,直到没有未打印的设计为止
打印每个设计后,都将其移到列表completed_models中
"""
while unprinted_designs:
current_design = unprinted_designs.pop()
#模拟根据设计制作3D打印模型的过程
print("Printing model:" + current_design)
completed_models.append(current_design)
#打印函数
def show_completed_models(completed_models):
"""显示打印好的所有模型"""
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
unprinted_designs = ['iphone case','robot pendant','dodecahedron']
completed_models = []
print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)
#课后习题8-9 魔术师:创建一个包含魔术师名字的列表,并将其传递给一个名为show_magicians()的函数,这个函数打印列表中每个魔术师的名字
print("\n课后习题8-9")
def show_magicians(names):
"""打印列表中每个魔术师的名字"""
for name in names:
print(name.title())
magicians = ['ann','amy','benny']
show_magicians(magicians)
#课后习题8-10 了不起的魔术师:基于练习8-9,编写一个名为make_great()的函数,对魔术师列表进行修改,在每个魔术师的名字中都加入字样"the Great"
#调用函数show_magicians(),确认魔术师列表确实改变了
print("\n课后习题8-10")
def make_great(change_names):
"""对魔术师列表进行修改,在每个魔术师的名字中加入字样the Great"""
i = 0
while i < len(change_names):
change_names[i] = "the Great " + change_names[i]
i += 1
def show_magicians(names):
"""打印列表中每个魔术师的名字"""
for name in names:
print(name.title())
magicians = ['ann','amy','benny']
make_great(magicians)
show_magicians(magicians)
#课后习题8-11 不变的魔术师:基于练习8-10,在调用make_great()时,向它传递魔术师列表的副本
#由于不想修改原始列表,请返回修改后的列表,并将其存储到另一个列表中
#分别使用这两个列表来调用show_magicians()
#确认一个列表包含的是原来的魔术师名字,而另一个列表包含的是添加了字样"the Great"的魔术师名字
print("\n课后习题8-11")
def make_great(change_names):
"""修改魔术师列表的副本,向每个魔术师的名字中添加'the Great'"""
i = 0
while i < len(change_names):
change_names[i] = "the Great " + change_names[i]
return change_names
def show_magicians(names):
"""打印列表中每个魔术师的名字"""
for name in names:
print(name.title())
magicians = ['ann','amy','benny']
great_magicians = make_great(magicians[:])
show_magicians(magicians)
show_magicians(great_magicians)
#课本例题8.5 传递任意数量的实参
#pizza.py
def make_pizza(*toppings):
"""打印顾客点的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
def make_pizza(*toppings):
"""概述要制作的比萨"""
print("\nMaking a pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
def make_pizza(size,*toppings):
"""概述要制作的比萨"""
print("\nMaking a " + str(size) +
"-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','extra cheese')
#user_profile.py
def build_profile(first,last,**user_info):
"""创建一个字典,其中包含我们知道的有关客户的一切"""
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key,value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile('albert','einstein',
location = 'princeton',
field = 'physics')
print(user_profile)
#课后习题8-12 三明治:编写一个函数,它接受顾客要在三明治中添加的一系列食材
#这个函数只有一个形参(它收集函数调用中提供的所有食材),并打印一条消息,对顾客点的三明治进行概述
#调用这个函数三次,每次都提供不同数量的实参
print("\n课后习题8-12")
def sandwich(*fillings):
"""打印顾客所点的三明治中所有的夹心的食材"""
print("\nMaking a sandwich with the following filling:")
for filling in fillings:
print("- " + filling)
sandwich('egg')
sandwich('egg','beef','lettuce')
#课后习题8-13 用户简介:复制前面的程序user_profile.py,在其中调用build_profile()来创建一个有关你的简介
#调用这个函数时,指定你的名和姓,以及三个描述你的键值对
print("\n课后习题8-13")
def build_profile(first,last,**user_info):
"""打印我的姓名,以及三个相关信息"""
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key,value in user_info.items():
profile[key] = value
return profile
my_info = build_profile('Sylvia','Wang',
loaction='Xian',
age=23,
gender='female')
print(my_info)
#课后习题8-14 汽车:编写一个函数,将一辆汽车的信息存储在一个字典中
#这个函数总是接受制造商和型号,还接受任意数量的关键字实参
#这样调用这个函数:提供必不可少的信息,以及两个名称-值对,如颜色和选装配件
#这个函数必须能够像下面这样进行调用:car = make_car('subaru','outback',color='blue',tow_package=True)
#打印返回的字典,确认正确地处理了所有信息
print("\n课后习题8-14")
def make_car(manufacturer,model,**car_info):
"""打印汽车的制造商,型号,及其其他信息"""
info = {}
info['manufacturer'] = manufacturer
info['model'] = model
for key,value in car_info.items():
info[key] = value
return info
car = make_car('subaru','outback',
color='blue',
tow_package='True')
print(car)
#课本例题8.6 将函数存储在模块中
print("\n课本例题8.6")
#导入整个模块
import Chapter_8_import_test
Chapter_8_import_test.make_pizza(16,'pepperoni')
Chapter_8_import_test.make_pizza(12,'mushrooms','green peppers','extra cheese')
#导入特定的函数
from Chapter_8_import_test import make_pizza
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','extra cheese')
#使用as给函数指定别名
from Chapter_8_import_test import make_pizza as mp
mp(16,'pepperoni')
mp(12,'mushrooms','green peppers','extra cheese')
#使用as给模块指定别名
import Chapter_8_import_test as C
C.make_pizza(16,'pepperoni')
C.make_pizza(12,'mushrooms','green peppers','extra cheese')
#导入模块中地所有函数
from Chapter_8_import_test import *
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','extra cheese')
#课后习题8-15 打印模型:将示例print_models.py中的函数放在测试文件中
#在print_models.py的开头编写一条import语句,并修改这个文件以使用导入的函数
print("\n课后习题8-15")
import Chapter_8_import_test as C
unprinted_designs = ['iphone case','robot pendant','dodecahedron']
completed_models = []
C.print_models(unprinted_designs,completed_models)
C.show_completed_models(completed_models)
#pizza.py
def make_pizza(size,*toppings):
"""概述要制作的比萨"""
print("\nMaking a " + str(size) +
"-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
#print_models.py
#处理函数
def print_models(unprinted_designs,completed_models):
"""
模拟打印每个设计,直到没有未打印的设计为止
打印每个设计后,都将其移到列表completed_models中
"""
while unprinted_designs:
current_design = unprinted_designs.pop()
#模拟根据设计制作3D打印模型的过程
print("Printing model:" + current_design)
completed_models.append(current_design)
#打印函数
def show_completed_models(completed_models):
"""显示打印好的所有模型"""
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)