8 函数
函数是带名字的代码块,用于完成具体的工作。要执行函数定义的特定任务,可直接调用该函数。
8.1 定义函数
输入:
#def定义函数、for_users()为函数名、以冒号结尾
def for_users():
#文档字符串通常用三个冒号引出来,用来注释,描述函数是做什么的
"""给用户say hello"""
print("hello,You have successfully defined the function ")
#直接调用for_users这个函数
for_users()
输出:
hello,You have successfully defined the function
[Finished in 67ms]
8.1.1 向函数传递信息
通过在这里添加username,可以让函数接收你给username指定的任何值。现在这个函数要求你在调用它的时候给username指定一个值。
输入:
def for_users(username):
"""给用户say hello"""
print(f"{username.title()},hello!You have successfully defined the function. ")
for_users("jinx")
输出:
Jinx,hello!You have successfully defined the function
[Finished in 67ms]
8.1.2 形参和实参
根据上一个例子变量username是一个形参,函数完成工作时所需要的信息。在调用函数时
for_users("jinx")中的"jinx"就是实参。
8.2 转递实参
1、位置实参,这要求实参的顺序与形参的顺序相同。
2、关键字实参,其中每个实参都由变量名和值组成;还可使用列表和字典。
8.2.1 位置实参
举例如下所示:
输入:
def cars(Producing_country,brand):
"""车辆信息"""
print(f"be from:{brand}")
print(f"made in:{Producing_country}")
cars("Japan","Toyota")
输出:
be from:Toyota
made in:Japan
[Finished in 68ms]
1). 多次调用函数
上一个例子只是简单调用了一次函数,如下为多次调用后的举例:
输入:
def cars(Producing_country,brand):
"""车辆信息"""
print(f"\nbe from:{brand}")
print(f"made in:{Producing_country}")
cars("Japan","Toyota")
cars("America","Dodge")
输出:
be from:Toyota
made in:Japan
be from:Dodge
made in:America
[Finished in 67ms]
2). 位置实参的顺序很重要
一定要注意位置实参的顺序,否则就会牛头不对马嘴。
8.2.2 关键字实参
关键字实参即是把实参中名称和值通过等号关联起来
输入:
def cars(Producing_country,brand):
"""车辆信息"""
print(f"\nbe from:{brand}")
print(f"made in:{Producing_country}")
cars(Producing_country="Japan",brand="Toyota")
输出:
be from:Toyota
made in:Japan
[Finished in 76ms]
8.2.3 默认值
如果在调用函数时,给形参提供了实参,python就会直接使用你所指定的实参,如果你没有给形参提供实参则会使用默认值。
.输入:
def cars(Producing_country='china',brand = '长安'):
"""车辆信息"""
print(f"\nbe from:{brand}")
print(f"made in:{Producing_country}")
cars()
输出:
be from:长安
made in:china
[Finished in 68ms]
8.2.4 避免实参错误
如下:
输入:
def cars(Producing_country,brand ):
"""车辆信息"""
print(f"\nbe from:{brand}")
print(f"made in:{Producing_country}")
cars()
输出:
TypeError: cars() missing 2 required positional arguments: 'Producing_country' and 'brand'
[Finished in 213ms]
报错原因:
1.没指定默认值
2.没输入实参来传给形参
8.3返回值
函数并非总是直接显示输出,它还可以处理一些数据,并返回一个或一组值。函数返回的值称为返回值。
8.3.1返回一个简单值
输入:
def people_name(first_name,last_name):
"""人名的全名"""
full_name=f'{first_name} {last_name}'
return full_name.title()
name = people_name('Lee','Sin')
print(name)
输出:
Lee Sin
[Finished in 93ms]
8.3.2 让实参变成可选的
输入:
#111111111
def people_name(first_name,last_name):
"""人名的全名"""
full_name=f'{first_name} {last_name}'
return full_name.title()
name = people_name('Lee','Sin')
print(name)
#222222222
def people_name(first_name,middle_name,last_name):
"""人名的全名"""
full_name=f'{first_name} {middle_name} {last_name}'
return full_name.title()
name = people_name('Jinx','dave','joker')
print(name)
def people_name(first_name,last_name,middle_name=''):
"""人名的全名"""
#检查是否提供了中间名
if middle_name:
full_name=f'{first_name} {middle_name} {last_name}'
else:
full_name=f'{first_name} {last_name}'
return full_name.title()
name = people_name('Jinx','dave','joker')
print(name)
name = people_name('Lee','Sin')
print(name)
输出:
Lee Sin
Jinx Dave Joker
Jinx Joker Dave
Lee Sin
[Finished in 61ms]
8.3.3 返回字典
在条件测试中,None相当于False。如果函数调用中包含形参age的值,这个值将被存储到字典中。这里if语句中采用了第六章添加键值对的办法。
输入:
def personal_information(first , second , last=None):
"""个人信息简介"""
information = {"name":first ,"sex":second }
if last:
information['age'] = last
return information
people = personal_information('jinx' , 'woman' , last=20)
print(people)
输出:
{'name': 'jinx', 'sex': 'woman', 'age': 20}
[Finished in 62ms]
8.3.4 结合使用函数和while循环
输入:
def peoples_name(first_name ,last_name):
"""全名"""
full_name = f"{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
data = peoples_name(f_name,l_name)
print(f"\nhello!,{data}.")
repl:
Please tell me your name!
enter'q'at any time to quit!
First_name:li
Last_name:qin
hello!,Li Qin.
Please tell me your name!
enter'q'at any time to quit!
First_name:q
***Repl Closed***
8.4 传递列表
将列表传递给函数后,函数就能直接访问其内容。如下例所示:
输入:
def everyone_users(names):
"""向列表中的用户发出问候"""
for name in names:
msg=f'hello,{name.title()}'
print(msg)
usernames =['jinx' , 'ez' , 'vi']
everyone_users(usernames)
输出:
hello,Jinx
hello,Ez
hello,Vi
[Finished in 67ms]
8.4.1 在函数中修改列表
以下为一家为用户提交的设计制作3D打印模型的公司的例子:
输入:
#定义函数包括两个的形参:一个需要打印的设计列表和一个打印好的模型列表。
def print_models(unprinted_designs,completed_models):
"""模拟打印每个设计,直到没有未打印的设计为止。"""
"""打印每个设计后,都将其移到列表completed_models中。 """
while unprinted_designs:
current_design = unprinted_designs.pop()
print(f"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 = ['phone case','robot pendant','dodecahedron']
completed_models = []
#函数调用
print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)
输出:
Printing model:dodecahedron
Printing model:robot pendant
Printing model:phone case
The following models have been printed:
dodecahedron
robot pendant
phone case
[Finished in 66ms]
该程序还演示了这样一种理念:每个函数都应只负责一项具体的工作,对于复杂的任务可以划分为多个函数进行调用
8.4.2 禁止函数修改列表
有时候,需要禁止函数修改列表,我们可以采用切片的方法
#禁止函数修改列表function_name(list_name_[:])
#函数调用
print_models(unprinted_designs[:],completed_models) #禁止函数修改列表function_name(list_name_[:])
show_completed_models(completed_models)
8.5 传递任意数量的实参
形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中这样就能传递任意数量的实参。
输入:
def make_pizza(*toppings):
"""概述要制作的比萨。"""
print("\nMaking a pizza with the following toppings:")
for topping in toppings:
print(f"- {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
[Finished in 89ms]
8.5.1 结合使用位置实参和任意数量的实参
注意*toppings一定要放在最后,python会先匹配位置实参和关键字实参然后在将余下实参都收集到最后一个形参当中
输入:
def make_pizza(size,*toppings):
"""概述要制作的比萨。"""
print(f"\nMaking a {size}-inch pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")
make_pizza(16,'pepperoni')
make_pizza(15,'mushrooms','green peppers','extra cheese')
输出:
Making a 16-inch pizza with the following toppings:
- pepperoni
Making a 15-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese
[Finished in 76ms]
8.5.2 使用任意数量的关键字实参
形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所有名称值对都放到这个字典中。
输入:
def build_profile(first,last,**user_info):
"""创建一个字典,其中包含我们知道的有关用户的一切。"""
user_info['first_name'] = first
user_info['last_name'] = last
return user_info
user_profile = build_profile('albert','einstein',location='princeton',field='physics')
print(user_profile)
输出:
{'location': 'princeton', 'field': 'physics', 'first_name': 'albert', 'last_name': 'einstein'}
[Finished in 79ms]
8.6 将函数存储在模块中
将函数存储在称为模块的独立文件中,再将模块导入到主程序中。import语句允许在当前运行的程序文件中使用模块中的代码。
8.6.1导入整个模块
1.创建一个函数模块取名为pizza.py
2.创建另一个模块,要调用被导入模块中的函数,可指定被导入模块的名称pizza和函数名make_pizza()
8.6.2 导入特定的函数
基本方法同上
如果需要导入多个函数模块在make_pizza后面用逗号
8.6.3 使用as给函数指定别名
8.6.4 使用as给模块指定别名
8.6.5 导入模块中的所有函数
要过春节了有点疲软ಠ_ಠ
———— 参考书籍Python编程:从入门到实践(第2版)埃里克·马瑟斯/袁国忠译