目录
1.定义函数
def greet_user(): #def告诉python要定义一个函数,这是函数定义,
#向Python指出了函数名,还可能在括号内指出函数为完成其任务需要
#什么样的信息
#在这里,greet_user()为函数名
"""显示简单的问候语""" #文档字符串
print("hello!") #函数体中代码
greet_user() #直接调用函数
输出:
hello!
要使用这个函数,可调用它。函数调用 让Python执行函数的代码
1.1向函数传递信息
可以让函数greet_user() 不仅向用户显示Hello! ,还可以对指定的用户打招呼。可以在函数定义时添加username。就可以让函数接收你给username的任何值
def greet_user(username):
print("Hello ! " + username.title())
greet_user("angel")
代码greet_user('angel') 调用函数greet_user() ,
并向它提供执行print 语句所需的信息。这个函数接受你传递给它的名字,并向这个人发出问候.
1.2实参和形参
前面函数 greet_user(username) 中 username 是一个形参
而 greet_user("angel") 则是一个实参
练习:
编写一个名为display_message() 的函数,它打印一个句子
编写一个名为favorite_book() 的函数,其中包含一个名为title 的形参。这个函数打印一条消息,如One of my favorite books is Alice in Wonderland 。调用这个函数,并将一本图书的名称作为实参传递给它。
2 传递实参
函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。
向函数传递实参的方式很多,可使用位置实参 ,这要求实参的顺序与形参的顺序相同;
也可使用关键字实参 , 其中每个实参都由变量名和值组成;还可使用列表和字典。
2.1 位置实参
调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。
为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参
def describe_pet(animal_type,pet_name):
"""显示宠物的信息 """
print("\n I have a " + animal_type + ".")
print("My " + animal_type + " 's name is " + pet_name.title() + "." )
describe_pet("cat","mimi")
describe_pet("dog","wangcai")
上面代码中 实参cat , dog 都存储到了 形参 animal_type 中 ,mimi, wangcai 则存储到了pet_name 中,根据顺序来的.
2.2 关键字实参
传递给函数的名称 — 值对。你直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆
def describe_pet(animal_type,pet_name):
print("I hava a " + animal_type)
print("My " + animal_type + " 's name is " + pet_name)
describe_pet(animal_type="cat",pet_name="mimi") #明确地指出了各个实参对应的形参
2.3 默认值
编写函数时,可给每个形参指定默认值 。在调用函数中给形参提供了实参时,Python将使用指定的实参值
def describe_pet(pet_name,animal_type="cat"): #默认值不能放在形参前面
print("I hava a " + animal_type)
print("My " + animal_type + " 's name is " + pet_name)
describe_pet("mimi")
输出:
I hava a cat
My cat 's name is mimi
提供的实参多于或少于函数完成其工作所需的信息时,将出现实参不匹配错误.
练习:
T恤 :编写一个名为make_shirt() 的函数,它接受一个尺码以及要印到T恤上的字样。
这个函数应打印一个句子,概要地说明T恤的尺码和字样。
使用位置实参调用这个函数来制作一件T恤;再使用关键字实参来调用这个函数。
城市 :编写一个名为describe_city() 的函数,它接受一座城市的名字以及该城市所属的国家。
这个函数应打印一个简单的句子,如Reykjavik is in Iceland 。
给用于存储国家的形参指定默认值。为三座不同的城市调用这个函数,且其中至少有一座城市不属于默认国家
3 返回值
函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值。函数返回的值被称为返回值 。在函数中,可使用return 语句将值返回到调用函数的代码行。 返回值让你能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序
返回简单值:
def get_formatted_name(fisrt_name,last_name):
full_name = fisrt_name + " " + last_name
return full_name.title()
musician = get_formatted_name("Angel","baby") #调用返回值的函数时,需要提供一个变量,用于存储返回的值
print(musician)
输出:
Angel Baby
让实参可选:
有时候,需要让实参变成可选的,这样使用函数的人就只需在必要时才提供额外的信息。可使用默认值来让实参变成可选的。
def get_formatted_name(fisrt_name,last_name,middle_name=""):
if middle_name : #Python将非空字符串解读为True ,因此如果函数调用中提供了中间名,if middle_name 将为True
full_name = fisrt_name + " " + middle_name + " " + last_name
return full_name
else:
full_name = fisrt_name + " " + last_name
return full_name
musicion = get_formatted_name("angel","baby")
print(musicion)
musicion = get_formatted_name("angel","baby","D")
print(musicion)
输出:
angel baby
angel D baby
返回字典:
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构
def build_person(fisrt_name,last_name,age,sex):
#函数build_person() 接受名、姓、年龄和性别,并将这些值封装到字典中
person = {"fisrt":fisrt_name,"last":last_name,"age":age,"sex":sex} #fisrt, last ,age ,sex 是他们的键
return person #返回person这个字典
musicion = build_person("angel","baby","22","man")
print(musicion)
输出 :
{'fisrt': 'angel', 'last': 'baby', 'age': '22', 'sex': 'man'}
结合使用函数和while循环:
def get_formatted_name(fisrt_name,last_name):
full_name = fisrt_name + "" + last_name
return full_name
while True:
print("输入'quit'进行退出")
f_name = input("请输入你的姓:")
l_name = input("请输入你的名:")
if f_name == "quit" or l_name =="quit":
break
else:
formatted_name = get_formatted_name(f_name,l_name)
print(formatted_name)
def get_formatted_name(fisrt_name,last_name):
full_name = fisrt_name + " " + last_name
return full_name
while True:
print("输入 'quit'进行退出")
f_name = input("请输入你的姓:")
if f_name == "quit":
break
l_name = input("请输入你的名:")
if l_name == "quit":
break
formatted_name = get_formatted_name(f_name,l_name)
print(formatted_name)
下面这段写的好点, 上面这段太拖沓
练习:
专辑:编写一个名为make_album() 的函数,它创建一个描述音乐专辑的字典。
这个函数应接受歌手的名字和专辑名,并返回一个包含这两项信息的字典。
使用这个函数创建三个表示不同专辑的字典,并打印每个返回的值,以核实字典正确地存储了专辑的信息。
4.传递列表
向函数传递列表很有用,这种列表包含的可能是名字、数字或更复杂的对象(如字典)。将列表传递给函数后,函数就能直接访问其内容
#假设有一个用户列表,我们要问候其中的每位用户。
usernames = ["job","angel","baby","gray"] #创建一个列表
def greet_users(names): #names作为形参
for name in names: #遍历 实参传给 形参
message = "hello " + name.title()
print(message)
greet_users(usernames) #将列表作为实参传递给函数
输出:
hello Job
hello Angel
hello Baby
hello Gray
在函数中修改列表:
将列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永久性的
为用户提交的设计制作3D打印模型的公司。需要打印的设计存储在一个列表中,打印后移到另一个列表中
unprinted_designs = ["xiaomi","huawei","iphone"]
completed_models = []
# while unprinted_designs :
# current_design = unprinted_designs.pop()
# completed_moodes.append(current_design)
# print(completed_moodes)
def print_models(unprinted_designs,completed_models):
while unprinted_designs:
current_design = unprinted_designs.pop()
completed_models.append(current_design)
def show_model(completed_models):
for completed_model in completed_models:
print(completed_model)
print_models(unprinted_designs,completed_models)
show_model(completed_models)
禁止函数修改列表:
有时候 需要禁止函数修改列表,在上个示例中,如果想保留unprinted_designs 的值,可以这样调用print_models()
function_name(list_name[:]) #在上个示例中,如果想保留unprinted_designs 的值,可以这样调用print_models()
print_models(unprinted_designs[:],completed_models)
练习:
魔术师:创建一个包含魔术师名字的列表,并将其传递给一个名为show_magicians() 的函数,这个函数打印列表中每个魔术师的名字
在你为完成刚才编写的程序中,编写一个名为make_great() 的函数,对魔术师列表进行修改,
在每个魔术师的名字中都加入字样“the Great”。调用函数show_magicians() ,确认魔术师列表确实变了。
5.传递任意数量的实参
有时候,你预先不知道函数需要接受多少个实参,好在Python允许函数从调用语句中收集任意数量的实参
def make_pizza(*toppings): #*toppings 中的*号让python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中.
print("制作披萨需要的配料是:")
for value in toppings:
print(value)
make_pizza("sala")
make_pizza("mike","cookie","humbug")
输出:
制作披萨需要的配料是:
sala
制作披萨需要的配料是:
mike
cookie
humbug
结合使用位置实参和任意数量实参
如果要让函数接受不同类型的 实参,必须在函数定义中将接纳任意数量 实参 的 形参 放在最后
def make_pizza(size,*toppings):
print("这个披萨的尺寸是 :" + size)
print("这个披萨的配料是 :")
for topping in toppings:
print(topping)
make_pizza("32","sala","cake","mike")
输出:
这个披萨的尺寸是 :32
这个披萨的配料是 :
sala
cake
mike
使用任意数量的关键字实参:
有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息
在这种情况下,可将函数编写成能够接受任意数量的键—值对——调用语句提供了多少就接受多少。
一个这样的示例 是 创建用户简介 :你知道你将收到有关用户的信息,但不确定会是什么样的信息
def build_profile(first_name,last_name,**user_info):
#这里user_info前面是两个*号, 和之前元组的不一样
"""创建一个字典,其中包含我们知道的有关用户的一切"""
profile = {}
profile["first_name"] = first_name
profile["last_name"] = last_name
for key,value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile("liu","jin",age = "23",sex = "nan")
#如果出现build_profile() got an unexpected keyword argument 'age' 这样的错误,就是 定义函数时,少了一个*号.
print(user_profile)
输出:
{'first_name': 'liu', 'last_name': 'jin', 'age': '23', 'sex': 'nan'}
练习:
三明治:编写一个函数,它接受顾客要在三明治中添加的一系列食材。
这个函数只有一个形参(它收集函数调用中提供的所有食材),并打印一条消息,对顾客点的三明治进行概述。
调用这个函数三次,每次都提供不同数量的实参。
汽车:编写一个程序,将一辆汽车的信息存储在一个字典中。这个函数总是接受制造商和型号,还接受任意数量的关键字实参。
这样调用这个函数:提供必不可少的信息,以及两个名称—值对,如颜色和选装配件。
6 .将函数存储在模块中
要让函数是可导入的,得先创造模块. 模 块 是拓展名为.py的文件,包含要导入到程序中的代码.
现在,我创建一个包含函数make_pizza()的模块.为此,我将 pizza.py中除了函数make_pizza()之外的其他代码删掉
# pizza.py
def make_pizza(size,*toppings):
print("这个披萨的尺寸是 :" + size)
print("这个披萨的配料是 :")
for topping in toppings:
print(topping)
然后,我在pizza.py所在的 目录 中创建一个名为making_pazzas.py的文件,这个文件导入刚创建的模块,再调用make_pizza()两次
#making_pizzas.py
import pizza
pizza.make_pizza(16,"cake") #pizza 是模块名,make_pizza是模块中的函数名
pizza.make_pizza(32,"mike","cookie")
Python读取这个文件时,代码行import pizza 让Python打开文件pizza.py
导入特定的函数:
from pizza import making_pizzas
使用as给函数别名:
from pizza import make_pizza as mp
mp(16, 'pepperoni')
mp(12, 'mushrooms', 'green peppers', 'extra cheese')
使用as给模块指定别名:
import pizza as p
p.make.pizza("12","cake")
导入模块中的所有函数:
from pizza import *