函数的定义
函数: 是组织好的,可重复使用的,用来实现特定功能的代码段。
- 作用: 提高程序的复用性,减少重复性代码,提高开发效率
函数的定义和调用


# 函数的定义
def my_len(data):
length = 0
for i in data:
length += 1
return length
# 函数的调用
print(f"字符串的长度是: {my_len('hello world~~')}")
注意事项
- 参数如不需要,可以省略(后续章节讲解)
- 返回值如不需要,可以省略(后续章节讲解)
- 函数必须先定义后使用
函数传参

- 函数定义中的参数,称之为形式参数
- 函数调用中的参数,称之为实际参数
- 函数的参数数量不限,使用逗号分隔开
- 传入参数的时候,要和形式参数一 一对应,逗号隔开
函数的返回值

- 通过return关键字,就能向调用者返回数据
None类型
如果函数没有使用return语句返回数据,那么函数有返回值吗?
- 实际上是: 有的。
- Python中有一个特殊的字面量: None,其类型是<class'NoneType'>
- 无返回值的函数,实际上就是返回了None这个字面量
- None表示: 空的、无实际意义的意思
- 函数返回的None,就表示,这个函数没有返回什么有意义的内容,也就是返回了空的意思。
- None有非常多的应用场景
- 用在函数无返回值上
- 用在if判断上, None等同于False
- 用于声明无内容的变量上

- 补充说明
- 在判断条件中 0、False、None、空字符串都视为False
- 其余值都视为True
函数的嵌套
所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数
- 如果函数A中,调用了另外一个函数B,
- 那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置


函数说明文档
函数是纯代码语言,想要理解其含义,就需要一行行的去阅读理解代码,效率比较低。
- 我们可以给函数添加说明文档,辅助理解函数的作用
- 通过多行注释的形式,对函数进行说明解释

- 在PyCharm编写代码时,可以通过鼠标悬停,查看调用函数的说明文档

变量的作用域
变量作用域指的是变量的作用范围 (变量在哪里可用,在哪里不可用)
局部变量
所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效

- 变量a是定义在`testA`函数内部的变量,在函数外部访问则立即报错
- 局部变量的作用: 在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量
所谓全局变量,指的是在函数体内、外都能生效的变量

global关键字
使用 global关键字 可以在函数内部声明变量为全局变量,如下所示
# 函数内的局部变量与全局变量重名时, 局部变量视为独立的的临时变量, 不影响全局变量
num = 100
def testA():
num = 200
print(num)
def testB():
print(num)
testA()
testB()

# 如果函数内需要修改全局变量的值, 需要使用global关键字
num = 100
def testA():
global num
num = 200
print(num)
def testB():
print(num)
testA()
testB()

ATM案例
案例效果
- 主菜单效果

- 查询余额效果

- 存、取款效果

思路分析

- 定义一个全局变量:money,用来记录银行卡余额(默认5000000)
- 定义一个全局变量:name,用来记录客户姓名(启动程序时输入)
- 定义如下的函数:
- 查询余额函数
- 存款函数
- 取款函数
- 主菜单函数
- 要求:
- 程序启动后要求输入客户姓名
- 查询余额、存款、取款后都会返回主菜单
- 存款、取款后,都应显示一下当前余额
- 客户选择退出或输入错误,程序会退出,否则一直运行
代码实现
print("欢迎来到ATM机")
name = input("请输入您的姓名")
money = 50000
def menu():
"""
主菜单, 提示用户操作
:return: 用户输入的数字
"""
print("--------------------主菜单--------------------")
print(f"{name},您好,欢迎来到ATM机,请选择操作: ")
print(f"查询余额\t[输入1]")
print(f"存款\t\t[输入2]")
print(f"取款\t\t[输入3]")
print(f"退出\t\t[输入4]")
return int(input("请输入您的选择: "))
def query_money(flag):
"""
余额查询
:param flag: 是否显示标题
:return: None
"""
if flag:
print("--------------------查询余额--------------------")
print(f"{name}您好,您的余额是: {money}元")
def add_money():
"""
用户存款
:return: None
"""
global money
print("--------------------存款--------------------")
num = int(input(f"{name},您要存入多少元: "))
money += num
print(f"{name},您存款{num}元成功")
query_money(False)
def take_money():
"""
用户取款
:return:
"""
global money
print("--------------------取款--------------------")
num = int(input(f"{name},您要取出多少元: "))
if num > money:
print(f"{name},您的余额不足{num}元")
query_money(False)
else:
money -= num
print(f"{name},您取款{num}元成功")
query_money(False)
while True:
# 主菜单
user_options_num = menu()
if user_options_num == 1:
query_money(True)
elif user_options_num == 2:
add_money()
elif user_options_num == 3:
take_money()
else:
print("欢迎下次光临,再见!")
break
函数多返回值
如果一个函数要有多个返回值,该如何书写代码?

-
按照返回值的顺序,写对应顺序的多个变量接收即可
-
变量之间用逗号隔开
-
支持不同类型的数据return
def func():
# 返回 (1,2)的元组
return 1, 2自动解包
x, y = func()
print(x, y)接收元组
z = func()
print(z)

函数传参方式
位置参数: 调用函数时根据函数定义的参数位置来传递参数

注意: 传递的参数和定义的参数的顺序及个数必须一致
关键字参数: 函数调用时通过"键=值"形式传递参数.
作用: 可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求.

注意: 函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
缺省参数: 省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值

- 注意: 所有位置参数必须出现在默认参数前,包括函数定义和调用
- 作用: 当调用函数时没有传递参数,就会使用默认是用缺省参数对应的值
不定长参数
不定长参数也叫可变参数, 用于不确定调用的时候会传递多少个参数(不传参也可以)的场景.
- 作用: 当调用函数时不确定参数个数时,可以使用不定长参数
- 不定长参数的类型:
- 位置传递

传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型
- 关键字传递

参数是"键=值"形式的情况下,所有的"键=值"都会被kwargs接受,同时会根据"键=值"组成字典.
-
示例
"""
不定长参数
"""print()函数的第一个形参,是一个*args不定长参数
不定长参数的后面,必须通过关键字传参
print("你好", "我好", "大家好", end="\t")
多种形式的形参
def func2(name, age, *args, **kwargs):
print(f"普通参数: {name},{age}")
print(f"元组收集参数: {args}")
print(f"字典收集参数: {kwargs}")func2("周杰伦", 11, 1, 2, 3, 4, 5, id=1, gender=2)

回调函数
把函数作为参数进行传递

- 函数compute, 作为参数,传入了test_func函数中使用。
- testfunc需要一个函数作为参数传入,这个函数需要接收2个数字进行计算,计算逻辑由这个被传入函数决定
- compute函数接收2个数字对其进行计算,compute函数作为参数,传递给了testfunc函数使用
- 最终,在test_func函数内部,由传入的compute函数,完成了对数字的计算操作
- 所以,这是一种,计算逻辑的传递,而非数据的传递。就像上述代码那样,不仅仅是相加,相见、相除、等任何逻辑都可以自行定义并作为函数传入。

匿名函数
函数的定义中
- def关键字,可以定义带有名称的函数
- lambda关键字,可以定义匿名函数(无名称)
- 有名称的函数,可以基于名称重复使用。
- 无名称的匿名函数,只可临时使用一次。
匿名函数定义语法

-
lambda是关键字,表示定义匿名函数
-
传入参数表示匿名函数的形式参数,如:x,y表示接收2个形式参数
-
函数体,就是函数的执行逻辑,要注意: 只能写一行,无法写多行代码
"""
匿名函数
"""
def func(callback):
result = callback(1, 2)
print(result)这些函数只用一次,不需要重复使用,使用lambda快速实现
func(lambda x, y: x + y)
func(lambda x, y: x - y)
func(lambda x, y: x * y)
func(lambda x, y: x / y)如果要重复利用,可以使用变量接收
变量名就是一个带名字的函数
add = lambda x, y: x + y
print(add(2, 2))