函数大模块整合
初级函数
一、函数的作用
需求:用户到ATM机取钱:
- 输入密码后显示“选择功能”界面
- 查询余额后显示“选择功能”界面
- 取200块钱以后显示“选择功能”界面
特点:显示“选择功能”界面需要重复输出给用户,怎么实现?
函数就是将一段具有独立功能的代码块 整合到一个整体并命名 ,在需要的位置调用这个名称即可完成对应的需求。
函数在开发过程中,可以更高效的实现代码重用
二、函数的使用步骤
1 定义函数
2 调用函数
函数名(参数)
注意:
1.不同的需求,参数可有可无
2.在python中,函数必须先定义后使用
需求:复现ATM取钱功能
① 搭建整体框架(复现需求)
print('密码正确登录成功')
# 显示‘选择功能’界面
print('查询余额完毕')
# 显示'选择功能'界面
print('取了2000元钱')
# 显示'选择功能界面'
② 确定’选择功能’界面内容
print('查询余额')
print('存款')
print('取款')
③ 封装”选择功能”
注意:一定是先定义函数,后调用函数
def select_fun():
print('----请选择功能----')
print('查询余额')
print('存款')
print('取款')
print('----请选择功能----')
注意:声明函数的那一行的上方必须要有两行的空行,否则会出现波浪线提示规范书写格式
成品:
# 封装ATM机功能选项 -- 定义函数
def select_fun():
print('----请选择功能----')
print('查询余额')
print('存款')
print('取款')
print('----请选择功能----')
print('密码正确登录成功')
# 显示‘选择功能’界面
select_fun()
print('查询余额完毕')
# 显示'选择功能'界面
select_fun()
print('取了2000元钱')
# 显示'选择功能界面'
select_fun()
三、 函数的注意事项
- 函数先定义后调用,如果先调用会报错
- 如果没有调用函数,函数里面的代码不会执行
- Debug运行测试之后会发现,当遇到函数调用之后再返回到我们定义函数的地方,接着向下执行缩进代码,执行完之后会回到调用函数的地方继续向下执行
四、函数的参数作用
# 思考:完成需求如下:一个函数完成两个数1和2的加法运算
def add_num():
result = 1 + 2
print(result)
add_num()
思考:上述add_num函数只能完成数字1和2的加法运算,如果想要这个函数变得更加灵活,可以计算任何用户指定的两个数字的和,该怎么编写?
分析:用户要在调用函数的时候指定具体数字,那么在定义函数的时候就需要接受用户指定的数字。函数调用时候指定的数字和定义函数时候接受的数字即是函数的参数。
# 定义函数时同事定义了接受用户数据的参数a和b,a和b是形参
def add_num(a, b):
result = a + b
print(result)
# 调用函数时传入了真实的数据10 和20,真实数据为实参
add_num(10, 20) #30
# 定义函数有2个参数,传入数据也要是2个否则会报错
五、函数的返回值作用
如: 我们去超市购物,比如买烟,给钱之后,售货员就会返回我们烟这个商品,在函数中,如果需要返回结果给用户需要使用函数返回值。
def buy():
return '烟'
print('ok')
# 使用变量保存函数返回值
goods = buy()
print(goods) #烟
# return 作用:
# 1. 负责函数返回值
# 2. 退出当前函数:导致return下方的所有代码(函数体内部)不执行
六、函数的说明文档
思考: 定义一个函数后,程序员如何书写成语能够快速提示这个函数的作用?
答: 注释
思考: 如果代码多,我们是不是需要在很多代码中找到这个函数定义的位置才能看到注释?如果想更方便的查看函数的作用怎么办?
答: 函数的说明文档。
函数的说明文档也叫函数的文档说明。
定义函数的说明文档
def 函数名(参数):
“““ 说明文档的位置 ”””
代码
……
查看函数的说明文档
help(函数名)
def sum_num(a, b):
""" 求和函数 """
return a + b
help(sum_num)
# sum_num(a, b)
# 求和函数
更高级的函数说明文档:
def sum_num(a, b):
"""
求和函数
:param a:参数1
:param b: 参数2
:return: 返回值
"""
return a + b
result = sum_num(1, 2)
help(sum_num)
# sum_num(a, b)
# 求和函数
# :param a:参数1
# :param b: 参数2
# :return: 返回值
当打出三双引号之后,在中间按一下回车键就会自动变为更高级的函数说明文档
七、函数的嵌套使用
所谓函数嵌套调用指的是一个函数里面又调用了另一个函数。
函数嵌套调用应用之打印横线图案:
# 首先创建一个函数可以打印一条横线
def print_line():
print('-'*20)
print_line()
#之后利用函数调用打印多条横线:
def print_lines(num):
i = 0
while i < num:
print_line()
i += 1
print_lines(5)
# 1. 求三个数之和
def sum_3num(a, b, c):
return a + b + c
result = sum_3num(1, 2, 3)
print(result) # 6
# 2. 求三个数平均值:
def average_num(a, b, c):
sumResult = sum_3num(a, b, c)
return sumResult / 3
result = average_num(1, 2, 3)
print(result) # 2.0
# 在python中只要涉及到除法,结果就是会变成浮点型
函数加强篇
一、变量作用域
变量作用域指的是变量生效的范围,主要分为两类:局部变量和全局变量。
·局部变量
所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效。
def testA():
a = 100
print(a)
testA() #100
print(a) # 报错:name 'a' is not defined
# 变量a是定义在 testA函数内部的变量,在函数外部访问则立即报错。
# 局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。
·全局变量
所谓全局变量,指的是在函数体内、外都能使用的变量。
a = 100
def testA():
print(a) # 访问全局变量a,并打印变量a存储的数据
def testB(): # 访问全局变量a,并打印变量a存储的数据
print(a)
testA() # 100
testB() # 100
如果某些函数体内部需要临时修改已经定义过的全局变量,只要重新声明就可以了.
def testB():
a = 200
print(a) # 200
经过debug验证,这样并不会修改全局变量当中a的值,可得:testB函数内部的a = 200 相当于是定义了一个局部变量。
那么,该如何在函数体内部修改全局变量呢?
def testB():
# global 关键字声明a是全局变量
global a
a = 200
print(a) # 200
testB()
print(a) # 200
二、多函数程序执行流程
一般在实际开发过程中,一个程序往往由多个函数(后面会细说 类 )组成,并且多个函数共享某些数据
·共用全局变量:
# 1.定义全局变量
glo_num = 0
def test1():
# 声明全局变量
global glo_num
# 修改全局变量
glo_num = 100
def test2():
# 调用test1函数中修改后的全局变量
print(glo_num)
print(glo_num) # 0, 因为修改的函数还没有执行
test1()
test2() # 100,先调用了函数1
# 返回值作为参数传递
# 1.定义两个函数:
# 2.函数一有返回值50;函数2把返回值50作为参数传入(自定义函数2要有形参)
def test1():
return 50
def test2(num):
print(num)
# 先得到函数一的返回值,再把这个返回值传入到函数二
result = test1()
print(result)
# 2.将函数返回值所在变量作为参数传递到test2函数
test2(result)
三、函数的返回值
思考: 如果一个函数要返回两个值,该怎么写呢
def return_num():
return 1, 2 # 返回的是元组
result = return_num()
print(result)
注意:
- return a, b 写法,返回多个数据的时候,默认是元组类型
- return后面可以连接列表,元组或字典,以返回多个值。
四、函数参数
一、位置参数
位置参数:调用函数时根据函数定义的参数位置来传递函数。
def user_info(name, age, gender):
print(f'您的姓名是{name},您的年龄是{age},您的性别是{gender}')
user_info('Tom', 20, '男') #您的姓名是Tom,您的年龄是20,您的性别是男
注意:
传递和定义参数的顺序及个数必须一致(多了或少了都会报错,但是顺序不一致会导致输出时候的数据无意义)
二、关键字参数
函数调用,通过”键=值”形式进行指定。可以让函数更加清晰,容易使用,同时也清除了参数的顺序需求。
user_info('rose', age=20, gender='女')
user_info('小明', gender='男', age=16)
注意:
- 函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。
- 当你重复输入同一个键的时候,系统便会自动给出警告!(位置参数一定要写在关键字参数的前面!)
user_info(gender='男', age=16, '小明')
三、 缺省参数
缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
def user_info(name, age, gender = '男'):
print(f'您的姓名是{name},您的年龄是{age},您的性别是{gender}')
user_info('Tom', 20)
user_info('Rose', 18, '女')
**注意:**函数调用时,如果为缺省参数传值则修改默认参数值;否则使用这个默认值
四、 不定长参数
不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以) 的场景。此时,可用包裹(packing)位置参数,或包裹关键字参数没来进行参数传递,会显得非常方便。
包裹位置传递:
注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递。
Python 解释器底层的代码对于接受不定长的关键字的参数的变量名或者形参的名字都是用这个名字,所以我们在书写的时候也延续这个名字使用。
当然的,这个args也可以被其他随便一个字符串代替(例如abc之类的),后面包裹关键字传递中的kwargs也是同理。
包裹关键字传递:
# 收集所有关键字参数,返回一个字典
def user_info(**kwargs):
print(kwargs)
user_info()
user_info(name='Tom')
user_info(age=20)
user_info(name='Tom', age=20)
综上:无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程。
组包:收集零散数据返回一个整体。
五、拆包和交换变量值
1. 拆包
·拆包:元组
def return_num():
return 100, 200
result = return_num()
print(result) # (100, 200)
num1, num2 = return_num()
print(num1) # 100
print(num2) # 200
·拆包:字典
dict1 = {'name': 'Tom', 'age': 18}
a, b = dict1
# 对字典进行拆包, 取出来的是字典的key
print(a) # name
print(b) # age
# 字典填写key值按key查找
print(dict1[a]) # Tom
print(dict1[b]) # 18
2. 交换变量值
需求: 有变量a=10和b=20,交换两个变量的值。
方法1:
借助第三变量存储数据。
a = 10
b = 20
# 1.定义中间变量
c = 0
# 2.将a的数据储存到c
c = a
# 3.将b的数据20复制到a,此时a = 20
a = b
# 4.将之前c的数据10复制到b,此时b = 10
b = c
print(f'a的值为{a}')
print(f'b的值为{b}')
显然的,非常麻烦
方法2:
a, b = 1, 2
a, b = b, a
print(f'a的值为{a}')
print(f'b的值为{b}')
# 两级反转!