函数
布尔微信:Matongxue_6
# 课程:函数
# 目标
- 函数的作用
- 函数的使用步骤
- 函数的参数作用
- 函数的返回值作用
- 函数的说明文档
- 函数嵌套
- 变量作用域
- 多函数程序执行流程
- 函数的返回值
- 函数的参数
- 可变和不可变类型
# 一.函数的作用
需求:用户到ATM机取款
- 输入密码后显示'选择功能'界面
- 查询余额之后显示"选择功能"界面
- 取2000元之后显示'选择功能'界面
特点:选择功能界面重复输出给用户,怎么实现呢?
函数就是将一段具有独立功能的代码块整合到一个整体并命名,在需要的位置调用这个函数的名字即可实现对应的功能。
函数在开发过程中,可以高效实现代码的复用性
# 二.函数的使用步骤
# 2.1 定义函数
def 函数(参数):
代码1
代码2
......
2
3
4
# 2.2 调用函数
函数名(参数)
注意:
- 不同的需求,参数可有可无
- 在python中,函数必须先定义后使用。
# 2.3 快速体验
需求:复现ATM取款功能
- 搭建整体框架(复现需求)
print('密码正确登录成功')
# 显示选择功能界面
print('查询余额完毕')
# 显示选择功能界面
print('取款2000元整')
# 显示选择功能界面
2
3
4
5
6
2.确定'选择功能'界面内容
print('查询余额')
print('取款')
print('存款')
2
3
3.封装"选择功能"
注意:一定是先定义函数,后调用函数
def select_option():
print('------请选择功能-------')
print('查询余额')
print('取款')
print('存款')
print('------请选择功能-------')
2
3
4
5
6
4.调用函数
在需要显示选择功能界面的时候调用选择功能函数。
print('密码正确登录成功')
select_option()
print('查询余额完毕')
select_option()
print('取款2000元整')
select_option()
2
3
4
5
6
# 三.函数的参数作用
思考:完成需求如下:一个函数完成两个数1和2的加法运算,如何书写程序?
# 定义函数
def add_sum1():
result = 1 + 2
print(result)
# 调用函数
add_sum1()
2
3
4
5
6
7
思考: 上述 add_num1 函数只能完成数字1和2的加法运算,如果想要这个函数变得更通用,可以计算任何用户指定的两个数字的和,如何书写程序?
分析:用户在调用函数的时候指定具体的数字,那么定义函数的时候就需要接受用户指定的数字。函数调用的时候指定的数字和定义函数的时候接收的数字即是函数的参数。
# 定义函数时同时定义了接收用户指定数据的参数a和b,a和b是形参
def add_sum1(a,b):
result = a + b
print(result)
# 调用函数时传入了真实的数据10,20,真实的数据为实参
add_sum1(10,20)
2
3
4
5
6
# 四.函数的返回值
例如:我们去药店买口罩,付过钱之后,店员给了我们口罩,在函数中,如果需要返回结果给用户,那么就需要使用函数的返回值。
def buy():
return '口罩'
# 使用变量保存函数的返回值
goods = buy()
print(goods)
2
3
4
5
# 4.1 应用
需求:制作一个计算器,计算任意两个数之后,并保存结果。
def calculate(a,b):
return a+b
# 用result变量保存函数的返回值
result = calculate(4,8)
print(result)
2
3
4
5
6
# 五.函数的说明文档
思考:定义一个函数后,程序员如何写程序能够快速提示函数的作用呢?
回答: 注释
思考:如果代码很多,我们怎么能知道调用函数的具体作用是什么呢?难道我们要一点点的去找到定义函数的位置吗?有没有更好查看指定函数的作用的办法呢?
回答:函数的说明文档
函数的说明文档也叫函数的文档说明
# 5.1 语法
- 定义函数的说明文档
def 函数名(参数):
'''
说明文档的位置
'''
代码
...
2
3
4
5
6
- 查看函数的说明文档
help(函数名字)
# 5.2 快速体验
#求和函数
def sum(a,b):
'''
求和函数
:param a:
:param b:
:return: a+b
'''
return a + b
help(sum)
2
3
4
5
6
7
8
9
10
11
# 六.函数嵌套调用
所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数
- 示例
def testB():
print('-----testB-----start')
print('testB执行的代码')
print('-----testB-----end')
def testA():
print('-----testA------start')
testB
print('-----testA------end')
testA()
2
3
4
5
6
7
8
9
- 效果
- 执行流程
如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次函数A执行的位置。
# 七.函数的应用
# 7.1 打印图形
1.打印一条横线
def print_one_line():
print('-'*10)
# 调用函数
print_one_line()
2
3
4
5
2.打印多条横线
def many_lines(n):
i = 1
while i <= n:
print_one_line()
i += 1
# 调用函数
many_lines(5)
2
3
4
5
6
7
8
# 7.2 函数计算
1.求三个数之和
#定义函数
def sum(a,b,c):
result = a+b+c
return result
#调用函数
result = sum(1,2,3)
print(result) # 6
2
3
4
5
6
7
2.求三个数平均值
def average(a,b,c):
result = sum(a,b,c)
mean = result/3
return mean
# 调用函数
result = average(2,4,6)
print(result) # 4.0
2
3
4
5
6
7
# 八.变量作用域
变量作用域指的是变量生效的范围,主要分为两类:局部变量和全局变量
- 局部变量
所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效
def testA():
a = 100
print(a)
testA() # 100
print(a) # 报错:name 'a' is not defined
2
3
4
5
变量a是定义在函数 testA 内部的变量,在函数外部访问则理解报错
局部变量的作用:在函数体内部,临时保存数据,当函数被调用完成后,则销毁局部变量
- 全局变量
所谓全局变量,指的是在函数体内,外都能生效的变量
思考:如果有一个数据,在函数A和函数B中都要使用,该怎么办?
回答:将这个数据存储在一个全局变量里面
# 定义一个全局变量a
a = 100
def testA():
print(a) #访问全局变量a,并打印变量a存储的数据
def testB():
print(a) #访问全局变量a,并打印变量a存储的数据
testA() # 100
testB() # 100
2
3
4
5
6
7
8
9
思考:testB函数需求修改变量a的值为200,如何修改程序?
a = 100
def testA():
print(a)
def testB():
a = 200
print(a)
testA() # 100
testB() # 200
print(f'全局变量是{a}') # 全局变量是100
2
3
4
5
6
7
8
9
10
11
12
思考:在testB函数内部的a=200中的变量a是在修改全局变量a吗?
答:不是。观察上述代码发现,全局变量最后打印出来仍然是100,而没有返回testB修改的200,这就证明修改失败。综上,testB函数内部的a=200是定义一个局部变量。
思考:如何在函数体内部修改全局变量?
a = 100
def testA():
print(a)
def testB():
# global 关键字,声明a是全局变量
global a
a = 200
print(a)
testA() # 100
testB() # 200
print(f'全局变量是{a}') # 全局变量是200
2
3
4
5
6
7
8
9
10
11
12
13
14
# 九.多函数程序执行流程
一般在实际开发过程中,一个程序往往由多个函数(后面只是中会讲解类)组成,并且多个函数共享某些数据,如下所示:
- 共用全局变量
# 1.共用全局变量
glo_num = 10
# 修改全局变量
def test1():
global glo_num
glo_num = 200
def test2():
print(glo_num)
# 调用test1函数修改全局变量
test1()
# 调用test2函数打印全局变量
test2() # 200
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 返回值作为参数传递
def test1():
return 50
def test2(num):
print(num)
# 调用test1函数把返回值保存到一个变量中
result = test1()
# 把保存test1函数返回结果的变量传给test2作为参数
test2(result) # 50
2
3
4
5
6
7
8
9
# 十.函数的返回值
思考:如果一个函数想返回两个结果怎么办?可以用两个return去实现吗?
def test1():
return 1
return 2
#调用test1()
result = test1()
print(result) # 1 函数遇到return就会终止程序
2
3
4
5
6
回答: 只执行了第一个return,原因是因为return可以退出当前函数,导致return下方的代码不会执行
思考:如果一个函数要有多个返回值,该如何书写代码?
def return_num():
return 1,2
result = return_num()
print(result) # (1,2)
2
3
4
5
注意:
- return a,b 写法,返回多个数据的时候,默认是元组类型。
- return后面可以连续列表,元组或者字典,以返回多个值。
# 十一. 函数的参数
# 10.1 位置参数
位置参数:调用函数的时候根据函数定义的参数位置来传递参数
def user_info(name,age,gender):
print(f'您的名字是{name},年龄是{age},性别是{gender}')
user_info('Bull',20,'男')
2
3
4
5
注意:传递和定义参数的顺序及个数必须一致
# 10.2 关键字参数
关键字参数: 函数调用,通过’键=值‘形式加以指定。可以让函数更加清晰,容易使用,同时也清楚了参数的顺序需求。
def user_info(name,age,gender):
print(f'您的名字是{name},年龄是{age},性别是{gender}')
# 调用函数
user_info('Bull',age=20,gender='男') #位置参数要放在关键字参数的后面,关键字参数不要求顺序,无所谓
user_info('Bull',gender='男',age=20)
2
3
4
5
6
7
注意: 函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。
# 10.3 缺省参数
缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
def user_info(name,age,gender='男'):
print(f'您的名字是{name},年龄是{age},性别是{gender}')
# 调用函数,使用默认参数,不传gender
user_info('Bull',18)
# 调用函数,更改默认的参数值
user_info('tom',age=23,gender='男')
# 调用函数,关键字参数不区分顺序,只要在位置参数后面就可以
user_info('jack',gender='男',age=25)
2
3
4
5
6
7
8
注意:函数调用时,如果为缺省参数传值则修改默认参数值;否则使用这个默认值
# 10.4 不定长参数
不定长参数:也可叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。
- 包裹位置参数传递
def user_info(*args):
print(args)
user_info('TOM') # ('TOM',)
user_info() # ()
user_info('tom',90) # ('tom', 90)
2
3
4
5
6
注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),
args是元组类型,这就是包裹位置传递。
- 包裹关键字参数传递
def user_info(**kwargs):
print(kwargs)
# 返回的结果是{'name': 'tom', 'age': 10, 'gender': '男'}
user_info(name='tom', age=10, gender='男')
2
3
4
5
# 函数编码练习
需求:
工作之中,会需要注册大量的账户。这时候编辑和记录名字就成为一个问题。
这里编写一个随机生成姓名函数
分析需求:
1.根据功能,方法名称可以定义为“get_random_name”
2.需求中描述“大量生成”,可以理解为需要批量功能。继而拓展设计思路,
决定实现①生成单个随机名
后进行再次包装,编写
②生成指定数量随机名
两个方法
3.题目中没有明确生成什么姓名,需要进一步确定。
最终确定生成中文姓名
具体设计
1.python里有random库(https://docs.python.org/zh-cn/3/library/random.html),
它可以随机生成一个数字、或者在列表里随机选择一个item
2.中文姓名,可以分为“姓氏”和“名”两部分。
3.所谓的随机姓名,可以设计成随机“姓氏”+“名”(姓氏数量*名数量=总随机姓名)。
姓氏 和 名字,可以分别储存为一个列表
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20