Python中的函数就是带名字的代码块,主要用于完成具体的工作。Python的函数用def关键字来声明,定义好函数名后,后面的所金行都属于函数的函数体,如下所示:
def test(t1): #def声明构建函数,函数名为test,其中t1是用来传递参数的形参 print(t1) #此处是函数的函数体 test('t2') #调用函数test(),函数内部的t2是被传递的值,即实参 #执行结果如下: t2
在Python的函数中,形参是函数完成其工作所需的一项信息,实参是调用函数式传递给函数的信息。通俗来说,形参用来接收调用方法时传递过去的实参,在接受到实参中的值以后,将其带入函数体中进行处理;而实参则是调用函数时被传递的值。向函数传递 实参的方法有很多,常见的方法有三个,即位置实参、关键字实参和默认值三种,如下所示:
##位置实参,实参的顺序要和形参的顺序一致 def describe_pet(animmal_type,pet_name): """显示宠物的信息""" print("\nI have a " + animmal_type + ".") print("My " + animmal_type + "'s name is " + pet_name.title() + ".") describe_pet('hamste','harry') #执行结果如下所示: I have a hamste. My hamste's name is Harry. #关键字实参,在调用时指定形参对应的实参,即键值对, #由于调用实参时指定了值,因此实参顺序可以不考虑 def describe_pet(animmal_type,pet_name): """显示宠物的信息""" print("\nI have a " + animmal_type + ".") print("My " + animmal_type + "'s name is " + pet_name.title() + ".") describe_pet(animmal_type = 'hamste',pet_name = 'harry') #执行结果如下所示: I have a hamste. My hamste's name is Harry. #默认值,在定义形参的时候,将部分或全部形参附上默认值, #当调用实参时,可以不引用赋有默认值的形参,这样输出结果就是默认值, #如果跟默认值不符,也可以在调用实参的时候给实参赋值 def describe_pet(animmal_type,pet_name = 'ben'): """显示宠物的信息""" print("\nI have a " + animmal_type + ".") print("My " + animmal_type + "'s name is " + pet_name.title() + ".") describe_pet(animmal_type = 'hamste',pet_name = 'harry') #执行结果如下所示: I have a hamste. My hamste's name is Harry.
调用函数的方式多种多样,在适合的环境下使用正确的方法,需要大量的练习和开发过程中的经验积累,当然容易理解很重要,课后习题答案如下所示:
--8-4 def make_shirt(size,printing = '英文'): print("这件衣服的尺码是" + size + ",上面印着" + printing + ".") make_shirt('xl','汉字') #输出结果如下所示: 这件衣服的尺码是xl,上面印着汉字.
对于函数的复杂应用,不得不提到返回值!函数处理返回的值被称为返回值,用return来声明,返回值的使用能够将程序大部分繁中的工作转移到函数中去,从而简化程序,如下所示:
#让实参变得可选 def get_formatted_name(first_name,last_name,middle_name = ''): """返回整洁的姓名""" full_name = first_name + ' ' + middle_name + ' ' + last_name return full_name.title() musician = get_formatted_name('john','lee','hooker') print(musician) musician = get_formatted_name('jimi','hendrix') print(musician) #输出结果如下所示: John Hooker Lee Jimi Hendrix
上例中定义函数get_formatted_name(),包含三个形参first_name、last_name和middle_name,其中形参middle_name因为赋默认值,因此放最后,然后执行函数体,将执行结果赋值给变量full_name,并在执行完毕后将执行结果full_name作为返回值,返回给调用get_formatted_name()函数的变量musician,然后打印变量musician,实现整个函数。
除了上例中返回的结果外,返回值还能返回字典,如下例所示:
#形参age,赋默认值为空 #当实参未调用age时,默认赋值为空 #当实参调用age时,进入if判断,age为字典person的键 #因此person['age'] 的值为形参age,调用的时候,数值传入形参age中 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',age = '16') print(musician) #输出结果如下所示: {'first': 'jimi', 'last': 'hendrix', 'age': '16'}
上例中定义函数build_person,包含三个形参first_name,last_name和age,其中形参age赋默认值为空,定义字典person用于存储实参数值,由于age有默认值空,因此进入if判断,当age有值时加入字典person,处理完毕后返回结果person,并将返回的结果存入调用方法build_person的变量musician,打印变量musician可获得结果。
函数体的逻辑可以简单也可以复杂,比如加上while循环的使用,可以让功能更加强大,如下所示:
#函数统一了输出的格式,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 you 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 + "!") #输出结果如下所示: Please tell me you name: (enter 'q' at any time to quit) First_name:a Last_name:b Hello,A B! Please tell me you name: (enter 'q' at any time to quit) First_name:q 进程完成,退出码 0
上例中处理方函数内while循环问题,并不复杂,下面是课后习题答案,如下所示:
#8-6 def city_country(city,country): cc = city + "," + country return cc.title() regime = city_country('santuago','chile') print((regime)) #输出结果如下所示: Santuago,Chile #8-7 def make_album(singer,album,number = ''): works = {'singer':singer,'album':album} if number: works['number'] = number return works result = make_album('周杰伦','Jay',10) print(result) #输出结果如下所示: {'singer': '周杰伦', 'album': 'Jay', 'number': 10} #8-8 def make_album(singer,album): works = singer + ',' + album return works.title() while True: print("请输入你喜欢的歌手信息") singer_name = input("singer:") if singer_name == 'q': break album_name = input("album:") if album_name == 'q': break result = make_album(singer_name,album_name) print(result) #输出结果如下所示: 请输入你喜欢的歌手信息 singer:周杰伦 album:Jay 周杰伦,Jay 请输入你喜欢的歌手信息 singer:q 进程完成,退出码 0 #8-8变形,增加number形参处理专辑内歌曲数量问题 def make_album(singer,album,number = ''): works = {'singer':singer,'album':album} if number: works['number'] = number output_works = works['singer'] + "," + works['album'] + "," + works['number'] else: output_works = works['singer'] + "," + works['album'] return output_works while True: print("请输入你喜欢的歌手信息") singer_name = input("singer:") if singer_name == 'q': break album_name = input("album:") if album_name == 'q': break numbers = input("number:") if numbers == 'q': break result = make_album(singer_name,album_name,numbers) print(result) #输出结果如下所示: 请输入你喜欢的歌手信息 singer:周杰伦 album:Jay number:10 周杰伦,Jay,10 请输入你喜欢的歌手信息 singer:周杰伦 album:Jay number: 周杰伦,Jay 请输入你喜欢的歌手信息
复杂的内容有时会通过列表传递到函数中进行处理,如下所示:
#以列表的形式向函数传参,通常结构如下 def greet_users(names): """向列表中的每位用户发出简单的问候""" for name in names: msg = "Hwllo," + name.title() + "!" print(msg) username = ['hannah','ty','margot'] greet_users(username) #输出结果如下所示: Hwllo,Hannah! Hwllo,Ty! Hwllo,Margot! #复杂的传参如下所示、 #定义函数print_models,包含形参unprinted_designs和completed_models def print_models(unprinted_designs,completed_models): """模型打印每个设计,直到没有未打印的设计为止 打印每个设计后,都将其移到列表completed_mode ls中 """ #执行while循环,将列表unprinted_designs中的数据传递到current_desgion中 while unprinted_designs: current_desgion = unprinted_designs.pop() #模拟根据设计制作3D打印模型的过程,即打印列表传递的过程 print("Prining model: " + current_desgion) completed_models.append(current_desgion) def show_completed_models(completed_model): """显示打印好的模型""" print("\nThe following modles have been printed:") for completed_model in completed_model: print(completed_model) #创建列表unprinted_designs和completed_models unprinted_designs = ['iphone case','robot pendant','dodecahedron'] completed_models = [] #定义变量print_models和show_completed_models负责传参 print_models(unprinted_designs,completed_models) show_completed_models(completed_models) #输出结果如下所示: Prining model: dodecahedron Prining model: robot pendant Prining model: iphone case The following modles have been printed: dodecahedron robot pendant iphone case
课后习题答案如下所示:
#8-9 def show_magicians(names): for name in names: print(name) names = ['a','b','c'] show_magicians(names) #输出结果如下所示: a b c #8-10 def make_great(unnames,names): while unnames: sname = unnames.pop() names.append(sname) def show_magicians(names): for name in names: print(name.title() + " the Great") unnames = ['a','b','c'] names = [] make_great(unnames,names) show_magicians(names) #输出结果如下所示: C the Great B the Great A the Great #8-11 def make_great(unnames,names): while unnames: sname = unnames.pop() names.append(sname.title() + " the Great") def show_magicians(names): for name in names: print(name) unnames = ['a','b','c'] names = [] make_great(unnames[:],names) #unnames[:]的作用在于传参时传递的是列表unnames的复制列表,不会修改原数据 show_magicians(names) print(unnames) print(names) #输出结果如下所示: #8-9 def show_magicians(names): for name in names: print(name) names = ['a','b','c'] show_magicians(names) #输出结果如下所示: a b c #8-10 def make_great(unnames,names): while unnames: sname = unnames.pop() names.append(sname) def show_magicians(names): for name in names: print(name.title() + " the Great") unnames = ['a','b','c'] names = [] make_great(unnames,names) show_magicians(names) #输出结果如下所示: C the Great B the Great A the Great #8-11 def make_great(unnames,names): while unnames: sname = unnames.pop() names.append(sname.title() + " the Great") def show_magicians(names): for name in names: print(name) unnames = ['a','b','c'] names = [] make_great(unnames[:],names) #unnames[:]的作用在于传参时传递的是列表unnames的复制列表,不会修改原数据 show_magicians(names) print(unnames) print(names) #输出结果如下所示: C the Great B the Great A the Great ['a', 'b', 'c'] ['C the Great', 'B the Great', 'A the Great']
处理日常问题时,有时因为数据量庞大,可能不知道你有多少个参数传递进来,因此Python有关于传递任意实参的处理方式,如下所示:
def make_pizz(*toppings): #在形参前面添加*,表示创建名为toppings的元组,将所有值都封装进去 """打印顾客点的所有配料""" print("\nMaking a pizz with the following topping:") for topping in toppings: print("- " + topping) make_pizz('pepperoni') make_pizz('mushrooms', 'green peppers', 'extra cheese') #输出结果如下所示: Making a pizz with the following topping: - pepperoni Making a pizz with the following topping: - mushrooms - green peppers - extra cheese #存在知道部分实参数量的情况,此时可用以下方式处理,知道实参的数据正常处理,不知道的用*批量处理 def make_pizz(size,*toppings): """概述要制作的披萨""" print("\nMaking a " + str(size)+ "-inch pizz with the following toppings:") for topping in toppings: print("- " + topping) make_pizz(16,'pepperoni') make_pizz(34,'mushrooms', 'green peppers', 'extra cheese') make_pizz(22) #输出结果如下所示: Making a 16-inch pizz with the following toppings: - pepperoni Making a 34-inch pizz with the following toppings: - mushrooms - green peppers - extra cheese Making a 22-inch pizz with the following toppings: #有时需要接收任意实参,但不知道实参是什么样的信息,此时可将函数编写成能够接受任意数量的键值对,将数据存放在字典中 def build_profile(first,last,**user_info): ##形参前面加两个**,表示创建名为user_info的字典 """创建一个字典,其中包含我们知道的有关用户的一切""" profile = {} profile["first_name"] = first profile['last_name'] = last #该出循环为=是为了任意实参取数,将实参传入入的键值对取出键和值,以profile[key] = value的形式存入字典profile中 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) #输出结果如下所示: {'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}
习题答案如下:
#8-12 def sandwich_toppings(*toppings): print(toppings) sandwich_toppings('mushroom','tomato','green peppers') #输出结果如下所示: ('mushroom', 'tomato', 'green peppers') #8-14 def make_car(manufacturer,model,**other_information ): car_information = {} car_information['manufacturer_name'] = manufacturer car_information["model_value"] = model for key,value in other_information.items(): car_information[key] = value return car_information car = make_car('subaru','outback',color = 'blue',tow_package = True) print(car) #输出结果如下所示: 'manufacturer_name': 'subaru', 'model_value': 'outback', 'color': 'blue', 'tow_package': True}
函数的优点之一是可以将代码块和主程序分离,将函数存储在称为模块的独立文件中,通过import导入的方式进入主程序,如下所示:
#test.py def make_pizz(size,*toppings): """概述要制作的披萨""" print("\nMaking a " + str(size) + "-invh pizz with the following toppings:") for topping in toppings: print("- " + topping) ############################### #导入整个模块 #test2.py import test1 test1.make_pizz(16,'pepperoni') test1.make_pizz(12,'mushroom','green peppers','extra cheese') print("-----------------导入整个模块-----------------") ############################### #导入模块中的特定函数,多个函数可用逗号隔开 from test1 import make_pizz make_pizz(16,'pepperoni') make_pizz(12,'mushroom','green peppers','extra cheese') print("-----------------导入模块中的特定函数-----------------") ############################### #给导入模块中的特定函数起别名 from test1 import make_pizz as mp mp(16,'pepperoni') mp(12,'mushroom','green peppers','extra cheese') print("-----------------给导入模块中的特定函数起别名-----------------") ############################### #给导入模块起别名 import test1 as p p.make_pizz(16,'pepperoni') p.make_pizz(12,'mushroom','green peppers','extra cheese') print("-----------------给导入模块起别名-----------------") ############################### #导入模块中的所有函数 from test1 import * make_pizz(16,'pepperoni') make_pizz(12,'mushroom','green peppers','extra cheese') print("-----------------导入模块中的所有函数-----------------") #输出结果如下所示: Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------导入整个模块----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------导入模块中的特定函数----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------给导入模块中的特定函数起别名----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------给导入模块起别名----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------导入模块中的所有函数----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------导入整个模块----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------导入模块中的特定函数----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------给导入模块中的特定函数起别名----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------给导入模块起别名----------------- Making a 16-invh pizz with the following toppings: - pepperoni Making a 12-invh pizz with the following toppings: - mushroom - green peppers - extra cheese -----------------导入模块中的所有函数----------------- #课后习题如下所示 #8-15 #test1 def print_models(unprinted_designs,completed_models): """模型打印每个设计,直到没有未打印的设计为止 打印每个设计后,都将其移到列表completed_mode ls中 """ while unprinted_designs: current_desgion = unprinted_designs.pop() #模拟根据设计制作3D打印模型的过程 print("Prining model: " + current_desgion) completed_models.append(current_desgion) def show_completed_models(completed_model): """显示打印好的模型""" print("\nThe following modles have been printed:") for completed_model in completed_model: print(completed_model) ############################### #test2 from test1 import * unprinted_designs = ['iphone case','robot pendant','dodecahedron'] completed_models = [] print_models(unprinted_designs,completed_models) show_completed_models(completed_models) #输出结果如下所示: Prining model: dodecahedron Prining model: robot pendant Prining model: iphone case The following modles have been printed: dodecahedron robot pendant iphone case Prining model: dodecahedron Prining model: robot pendant Prining model: iphone case The following modles have been printed: dodecahedron robot pendant iphone case