8.函数
函数:有名字的代码块,用于完成具体的工作。
8.1 定义函数
def +函数名称(形参):
‘’’ ‘’’ 三引号构成文档字符串,描述函数的作用
其中定义函数时使用的是形参,是变量类型的总称;
实参是实际调用函数时传递给函数的信息;
例如,形参表示“一种蔬菜”,实参是具体的蔬菜“土豆”“胡萝卜”“青椒”
8.2 传递实参
函数中有多个形参,调用函数时也有多个实参
- 位置实参:基于实参的顺序关联到相应位置的形参向函数传递信息
- 关键字实参:通过 名称—值对 向函数传递信息,直接在实参中将名称和值关联,避免混淆,就是将形参与具体的对应的实参相关联,调用函数时明确写出
形参=‘实参’
- 默认值:定义函数时设置好形参的默认值,如果没有制定实参,就使用该默认值。
8.3 返回值
函数并非直接显示输出,也可显示希望得到的结果,例如用函数处理数据需要返回一个或一组值的时候,用return使函数返回到调用函数的代码行。
- 返回简单值:调用返回值的函数时,提供一个变量用于存储返回的值
- 实参可选:使用默认值
- 返回字典
- 函数与while循环
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 to quit')
f_name = input('first name')
if f_name == 'q':
break
l_name = input('last name')
if l_name == 'q':
break
name = get_formatted_name(f_name,l_name)
print('\nHello, '+name)
def make_album(singer, album, number=''):
'''描述音乐专辑的字典'''
if number:
message = {'singer name': singer, 'album name': album, '数量': int(number)}
else:
message = {'singer name': singer, 'album name': album}
return message
如果 number 参数的默认值是空字符串 ‘’,则在调用函数时,如果不传入具体的值,则 number 参数会被解释为字符串类型。如果你需要将其解释为数值类型,可以在函数内部使用 int() 函数进行转换
练习
def make_album(singer,album,number=''):
'''描述音乐专辑的字典'''
if number:
message = {'singer name':singer,'album name':album,'数量':number}
else:
message = {'singer name':singer,'album name':album}
return message
while True:
print('\n输入专辑的歌手和名称')
print('\n输入q退出循环')
s = input('输入歌手')
if s == 'q':
break
al = input('输入专辑')
if al == 'q':
break
a = make_album(s,al)
print(a)
练习
def show_magicians(names):
for name in names:
print('\n'+name)
magucians = ['anny','jack']
show_magicians(magucians)
8.4 传递列表
在函数中修改列表
- 用上一节的例子,分别用两个函数实现修改列表和打印列表的功能
#打印模型
def print_models(unprinted_designs,completes_models):
while unprinted_designs:
current_design = unprinted_designs.pop()
print('打印模型:'+current_design)
completes_models.append(current_design)
def show_completed_models(completed_models):
for completed_model in completed_models:
print('\n'+completed_model)
unconfirmed_users = ['alice','brian','candace']
confirmed_users = []
print_models(unconfirmed_users,confirmed_users)
show_completed_models(confirmed_users)
- 禁止函数修改列表,使用副本
使用列表切片创建列表副本,可以保证原列表不被修改。
例如在上面的代码中如果要保留原来的列表unconfirmed_users = ['alice','brian','candace']
,
只需要在调用’print_models(unprinted_designs,completes_models)'函数时,将实参改为列表unconfirmed_users的副本,print_models(unconfirmed_users[:],confirmed_users)
但在处理大型列表时,这样会消耗时间和内存
练习
#魔术师
def show_magicians(magicians):
for magician in magicians:
print('\n'+magician)
def make_great(magicians,great_magicians):
while magicians:
current_magician = magicians.pop()
great_magicians.append('the Great '+current_magician)
return great_magicians
magicians = ['anny','honny','jack','mary']
great_magicians = []
#show_magicians(magicians)
completed_magicians = make_great(magicians[:],great_magicians)
show_magicians(magicians)
show_magicians(completed_magicians)
8.5 传递任意数量的实参
将实参封装到一个元组中
形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。
def make_pizza(*toppings):
for topping in toppings:
print('\n-'+topping)
-
结合使用位置实参和任意数量实参
Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。创建元组 -
使用任意数量的关键字实参
不知道要接受实参的类型和数量时,将函数写成能接受任意数量的名称—值对。创建字典
定义函数时创建一个空字典用于存储键值对。
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('anny','huang',location='iceland')
print(user_profile)
练习
def make_car(maker,size,**others):
information = {}
information['制造商']=maker
information['型号']=size
for key,value in others.items():
information[key]=value
return information
mycar = make_car('特斯拉','model3',color='red',price='30w')
print(mycar)
8.6 将函数存储在模块中
更进一步地将代码行与主程序分离,将函数存储在独立文件(模块)中,再将模块导入到主程序,在当前的程序文件中通过inport语句使用模块中的代码。
- 导入整个模块
模块是扩展名为.py的文件,调用模块中的函数的代码行module_name.function_name
下例中,将定义函数make_car()的代码文件命名为pizza.py,在另一个程序中 用import语句导入模块pizza,并调用pizza文件中的函数make_car()
import pizza
mycar = pizza.make_car('特斯拉','model3',color='red',price='30w')
print(mycar)
- 导入特定的函数
导入模块中的特定函数的代码行from moudle_name import function_0,function_1
多个函数之间用逗号分隔,此时因为显式地导入了函数fuction,在调用时可以直接指定名称即可。 - 使用as给函数指定别名
当导入的函数与程序中现有的名称冲突时,可以指定别名。from moudle_name import function_name as fn
例如from pizza import make_pizza as mp mp(12,'pepperoni')
- 使用as给模块指定别名
代码行为import moudle_name as mn
例如import pizza as p
- 导入模块中的所有函数
使用‘*’运算符可以导入模块中的所有函数
例如from pizza import *
但是这样导入,如果有名称相同的函数或比那辆,会覆盖函数。 - 编写函数的指南
函数名称只使用小写字母和下划线;
函数定义后面注释功能,使用文档字符串注明需要的实参以及返回值的类型;
给形参指定默认值时和函数调用中的关键字实参,等号两边不要有空格;
所有的import语句都应放在文件开头。
练习
将8.4-1中打印模型的函数放在文件print_model.py中,在主程序中调用该模块
import print_model as pm
def show_completed_models(completed_models):
for completed_model in completed_models:
print('\n'+completed_model)
unconfirmed_users = ['alice','brian','candace']
confirmed_users = []
pm.print_models(unconfirmed_users,confirmed_users)
show_completed_models(confirmed_users)