1. 函数的介绍
函数是 实现具有特定功能的代码块
Python中预制了许多内置函数,也可以根据自己的需求创建自定义的函数
隐藏实现功能的细节
代码的复用
提高可读性,便与调试
def 函数名(形参1, 形参2...):
要运行的代码块(函数体)
return 返回的数据(返回值)
函数名要有描述性,建议使用下划线的格式: 动作_描述()
在函数体内定义的变量是局部变量,只能作用于该函数
2. 形参和实参
2.1 形参/实参介绍
# 定义一个简单的问候函数
def print_hello(username):
print("hello,{}".format(username))
# 调用函数,传入参数
print_hello("world")
-- run --
hello,world
以上示例中,变量 username是一个形参 :函数完成其工作所需的一项信息,在调用函数中,值 "world"是一个实参 :实参是调用函数时传递给函数的信息,将实参传递给函数 print_hello() ,这个值被存储在形参 username 中
函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参,接下来会介绍向函数传递实参的方式
2.2 位置实参
位置实参:要求实参的顺序与形参的顺序对应
定义:def 函数名(形参1, 形参2, 形参3):
调用:函数名(实参1, 实参2, 实参3)
位置实参的顺序很重要,如果实参的顺序与形参不相同,最终的函数结果可能出乎意料
# 定义一个宠物信息函数
def pet_describe(pet_type, pet_name):
"显示宠物类型和名字"
print("我的宠物是一只{},它的名字是{}".format(pet_type, pet_name))
# 实参与形参顺序相同
pet_describe("猫", "大橘")
# 实参与形参的顺序不同
pet_describe("大橘", "猫")
-- run --
我的宠物是一只猫,它的名字是大橘
我的宠物是一只大橘,它的名字是猫
2.3 关键字实参
关键字实参:每个实参都由变量名和值组成
定义:def 函数名(形参1, 形参2, 形参3):
调用:函数名(形参2=实参2, 形参3=实参3, 形参1=实参1)
关键字实参是传递给函数的 名称-值 对,直接在实参中将名称和值关联起来,因此无需考虑函数调用中的实参顺序
# 接着用上面位置实参的示例
def pet_describe(pet_type, pet_name):
"显示宠物类型和名字"
print("我的宠物是一只{},它的名字是{}".format(pet_type, pet_name))
# 明确指出了各个实参对应的形参,无需关注参数顺序
pet_describe(pet_type="猫", pet_name="大橘")
pet_describe(pet_name="大橘", pet_type="猫")
-- run --
我的宠物是一只猫,它的名字是大橘
我的宠物是一只猫,它的名字是大橘
使用关键字实参时,务必准确的指定函数定义中的形参名
2.4 混合传参
使用位置实参与关键字实参混合使用的方式
使用混合传参时,关键字参数必须在位置参数后面
# 位置参数要放在最前面
def pet_describe(pet_type, pet_name, age):
"显示宠物类型和名字"
print("我的宠物是一只{},它的名字是{},今年{}岁".format(pet_type, pet_name, age))
pet_describe("猫", age=1, pet_name="大橘")
-- run --
我的宠物是一只猫,它的名字是大橘,今年1岁
2.5 限制位置实参
定义:def 函数名(形参1, *, 形参2, 形参3):
调用:函数名(实参1, 形参2=实参2, 形参3=实参3)
星号 * 代表之后所有参数传参时 必须使用关键字传参
# *号之后的都必须使用关键字传参法,否则报错
def pet_describe(pet_type, *, pet_name, age):
"显示宠物类型和名字"
print("我的宠物是一只{},它的名字是{},今年{}岁".format(pet_type, pet_name, age))
pet_describe("猫", "大橘", 1)
-- run --
Traceback (most recent call last):
File "D:\Python\imooc\2.Python函数与模块\2.1.函数的定义与实现\2.1.1.function\test.py", line 5, in
pet_describe("猫", "大橘", 1)
TypeError: pet_describe() takes 1 positional argument but 3 were given
# 类型错误:pet_describe()接受1个位置参数,但给出了3个
2.6 设置参数的默认值
定义:def 函数名(形参=默认值):
在定义函数时,可以根据需要给指定的形参设置默认值
在调用函数中如果给该形参提供了实参,则使用指定的实参值,否则使用形参的默认值
设置默认值时,在形参列表中必须 先列出没有默认值的形参 ,再列出有默认值的形参 ,这让Python依然能够正确的解读位置实参
# 给设置了默认值的形参指定实参时,也可以用位置实参
def pet_describe(pet_name, age, pet_type="猫"):
"显示宠物类型和名字"
print("我的宠物是一只{},它的名字是{},今年{}岁".format(pet_type, pet_name, age))
pet_describe("大橘", 1)
pet_describe("大白", 0.5, "狗")
-- run --
我的宠物是一只猫,它的名字是大橘,今年1岁
我的宠物是一只狗,它的名字是大白,今年0.5岁
定义:def 函数名(形参=''):
通过给形参设置空字符串的默认值后,实参就变成可选的了,这样使用函数就只需要在必要时才提供额外的信息
# 姓 + 名 + 中间名(可选)组成完整的名字
def get_formatted_name(first_name, last_name, middle_name=''):
"返回完整的姓名"
if middle_name:
full_name = "{} {} {}".format(first_name, middle_name, last_name)
else:
full_name = "{} {}".format(first_name, last_name)
return full_name.title()
print(get_formatted_name("jimi", "hendrix"))
print(get_formatted_name("john", "hooker", "lee"))
-- run --
Jimi Hendrix
John Lee Hooker
2.7 使用序列传参
调用:函数名(*序列名)
序列不是Python中的某一种数据类型,而是一种数据结构的统称,如: 列表、元组、数字序列、字符串等 都称为序列,具体请移步 Python序列
# 定义一个简单的数学计算函数
def calc(a, b, c):
d = (a + b) * c
return d
# 位置传参
print(calc(1, 5, 10))
# 使用列表序列传参
num_list1 = [2, 4, 6]
print(calc(*num_list1))
-- run --
60
36
# 函数内定义了遍历语句,所以列表元素是依次传入,不需要加*
def greet_users(names):
"问候列表中的每个用户"
for name in names:
print("Hello,{}".format(name))
username = ["张三", "李四", "王五"]
greet_users(username)
-- run --
Hello,张三
Hello,李四
Hello,王五
2.8 使用字典传参
调用:函数名(**字典名)
使用字典传参时,类似于关键字传参,字典key的排列顺序无需对应形参的顺序,但是两者的名称、数量必须一致
# 定义一个简单员工信息函数
def fun_dict(name, hiredate, tel, dept):
print("{p1}隶属于{p4},电话:{p3},入职如期:{p2}".format(p1=name, p2=hiredate, p3=tel, p4=dept))
# 字典传参,key的名称要和形参对上,key的数量也要和形参数一致
dict1 = {'name':'张三','hiredate':'2020-06-27','dept':'技术部','tel':13012345678}
fun_dict(**dict1)
-- run --
张三隶属于技术部,电话:13012345678,入职如期:2020-06-27
3. 函数的返回值
3.1 函数中的return
参数是函数的输入数据,而返回值则是函数的输出结果
return 不是必须的,return语句 执行后,函数将中断执行
return解释.png
无return的函数.png
return与print区别.png
上述回答来自知乎用户“sqybi”,个人觉得通俗易懂,就摘录下来了,感谢大佬的解惑!
# 示例1:print
def print_hello():
print("hello")
print_hello()
str1 = print_hello()
print(str1)
-- run --
hello
hello
None
# 示例2:return
def print_hello():
return "hello"
print_hello()
print(print_hello())
str2 = print_hello()
print(str2)
-- run --
hello
hello
上述示例中,print是将结果打印在标准输出(屏幕)上,所以直接调用函数名就能执行打印;return是将结果保存至内存,打印时需要借助print函数
使用print的函数赋值时,由于没有返回值,仅有打印屏幕的操作,所以赋值变量返回的是 None ;而使用return的函数赋值时,将保存在内存中的返回值赋值给变量,所以赋值变量有返回值
3.2 返回值包含多个数据
在函数内定义嵌套字典,调用函数时使用不同的索引就可以获取多个返回数据
# 定义一个包含公司内信息的嵌套字典函数(仅列举部分信息)
def get_detail_info():
dict1 = {
"employee": [
{"name": "张三", "salary": 3000},
{"name": "李四", "salary": 4000}
],
"device": [
{"id": "88888888", "title": "xx笔记本"},
{"id": "66666666", "title": "xx台式机"}
],
"...": [{}, {}],
"......": [{}, {}]
}
return dict1
# 获取员工张三的薪资信息
d = get_detail_info()
sal = d.get("employee")[0].get("salary")
print(sal)
# 获取xx台式机设备的id号
dev = d.get("device")[1].get("id")
print(dev)
-- run --
3000
66666666