函数Functions
代码新格式
以前
1 # 执行代码
现在
1 2 3 4 5 def run(): # 执行代码 run()
函数功效预览
使用前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 def run(): print("请选择操作") print("1. 加法") print("2. 减法") print("3. 乘法") print("4. 除法") print("0. 退出") command = int(input()) while command: value1 = float(input()) value2 = float(input()) if command == 1: result = value1 + value2 elif command == 2: result = value1 - value2 elif command == 3: result = value1 * value2 elif command == 4: result = value1 / value2 print(result) print("请选择操作") print("1. 加法") print("2. 减法") print("3. 乘法") print("4. 除法") print("0. 退出") command = int(input()) run()
功能抽离 与 转接调用
1+2+3+4+5+6+7+8+9 10 11 12*13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # 功能抽离def print_menu(): print("请选择操作") print("1. 加法") print("2. 减法") print("3. 乘法") print("4. 除法") print("0. 退出") def run(): # 转接调用 print_menu() command = int(input()) while command: value1 = float(input()) value2 = float(input()) if command == 1: result = value1 + value2 elif command == 2: result = value1 - value2 elif command == 3: result = value1 * value2 elif command == 4: result = value1 / value2 print(result) print("请选择操作") print("1. 加法") print("2. 减法") print("3. 乘法") print("4. 除法") print("0. 退出") command = int(input()) run()
收益
化繁为简,段落归纳
将一大部分逻辑紧凑的代码进行打包
打包后 需要起个名字,可以用来总结段落大意
代码重用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29+30*31 32 33 34 35 # 功能抽离def print_menu(): print("请选择操作") print("1. 加法") print("2. 减法") print("3. 乘法") print("4. 除法") print("0. 退出") def run(): # 转接调用 print_menu() command = int(input()) while command: value1 = float(input()) value2 = float(input()) if command == 1: result = value1 + value2 elif command == 2: result = value1 - value2 elif command == 3: result = value1 * value2 elif command == 4: result = value1 / value2 print(result) # 代码重用 print_menu() command = int(input()) run()
收益
代码重用,重复代码消除
函数基础语法
基本元素
1 2 3 4 5 6 7 8 9 def run(): f() # 调用 def f(): # 声明 \ print("Hello") # 实现 -*- 定义 run()
函数的声明与实现
1 2 3 def 函数名(): <statements>
函数声明后,上下均可使用
注意:缩进
调用语法
1函数名()
执行规则

遇到函数,原函数暂停
执行被调用函数
结束后,再恢复执行原函数
1 2 3 4 5 6 7 8 9 10 11 def run(): 1 f() 2 def f(): 3 run()
执行顺序:1 3 2
挑战
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 def run(): print(11) h() print(12) f() print(13) def f(): print(21) g() print(22) h() print(23) def g(): print(31) h() print(32) def h(): print(41) run()
答案
run 11 h 41 12 f 21 g 31 h 41 32 22 h 41 23 13
函数生命周期Function Lifecycle
函数内的变量
1 2 3 4 5 6 7 8 9 10 def run(): a = 1 f() print(a) def f(): a = 1 a += 1 print(a)
你会看见什么
2 1
2 2
规则
每个函数有自己的数据空间,用于存储变量,且相互独立

函数间的数据传输
希望把数据 从一个函数里 传到 另外一个函数里

函数级别的 IO | 专业名词 | 数据传输方向 |
---|---|---|
输入 | 参数 | 从 外面 进入到 函数里 |
输出 | 返回值 | 从 函数里 流出到 外面 |
函数调用的完整生命周期
调用前

开始调用 f,准备变量空间
调用 f 时,为 被调用函数 f,开启单独变量空间
run 可使用 参数 将一些值 带到 函数 f的 新的变量空间

运行 被调用函数 f
被调用的函数 f 运行时,如果需要开变量,会开在自己的空间里

被调用函数 f 执行结束,准备返回
有些函数有返回值,此时会带着返回值 回到 刚才的函数 run

调用结束,销毁函数 f
结束后,会将 被调用函数 f 和对应的变量空间,彻底销毁,就当没发生过

参数Parameters
是什么
变量,只不过可以接受传值
函数的输入

参数声明
变量定义,用 ,
分割
1 2 def f(a, b): ...
函数调用时传参
1 2 3 4 5 def run(): f(3, 4) run()
函数调用前表达式缩合
1 2 3 4 5 6 7 8 9 10 11 12 13 def run(): c = 3 d = 4 e = c + d = 3 + 4 = 7 f(c, d) f(3, 4) def f(a, b): a = 3 b = 4 print(a) print(b) run()
传输的是值,不是变量
是数据格里的数据,而不是 数据格子

1 2 3 4 5 6 7 8 9 10 11 def run(): a = 1 f(a) print(a) def f(a): a = 9 run()
上面代码运行完了,你会看到什么
1
9
实参 与 形参
中文 | 英文 | 意义 |
---|---|---|
实参 | arguments | 传到参数里的值 |
形参 | parameters | 接收参数值的那个参数变量 |
传参数量匹配
传过去的和接收的,必须一致,多了也不行,少了也不行
1 2!3 4!5 6 7 8 9 10 11 def run(): f() f(1) f(1, 2) def f(a): print(a) run()
顺序传输Positional Keywords
按顺序传参,一个个传输
1 2 3 4 5 6 7 8 9 10 11 def run(): a = 1 b = 2 f(b, a) def f(a, b): print(a + ", " + b) run()
上面代码运行完了,你会看到什么
1, 2
2, 1
默认值与缺省传输Default Argument Values
参数可以设置默认值,从而可以接受传输时,这个参数没有接到值
1 2 3 4!5 6 7 8 9 10 11 def run(): f(1) f(1, 2) f(1, 2, 3) def f(a, b=1): print(a, b) run()
你会看到
< <1, 11, 2
然后报错
注意:
默认值的参数,必须在没有默认值的参数的后面
指名传输Keyword Arguments
传输时,可以显式写出参数名,从而指定传输给对应的值
1 2 3 4 5 6 7 8 9 10 11 def run(): a = 1 b = 2 f(b = a, a = b) def f(a, b): print(a + ", " + b) run()
上面代码运行完了,你会看到什么
1, 2
2, 1
混合规则
先 顺序 再 指名
当 顺序传输 和 指名传输 同时存在时,指名传输 必须在 顺序传输 的后面
1 print(1, end="")
不能重叠
当 顺序传输 和 指名传输 同时存在时,互相不能同时给一个变量传输
1 2!3 4 5 6 7 def run(): f(1, a=1) def f(a, b): print(a) print(b)
不能缺
顺序传输 和 指名传输 必须覆盖到所有 没有默认值的参数
1 2!3 4 5 6 7 8 9 def run(): f(1, c) def f(a, b, c, d=4): print(a) print(b) print(c) print(d)
返回值Return Value
是什么
用来给 调用方 返回 结果使用
函数的输出
返回值
1 2 3 def f(): return 1
变量接住函数返回值
函数表达式 会缩合成 函数的返回值
1 2 3 <4 def run(): a = f() = 1 print(a) 1
函数返回前的表达式缩合
1 2 3 <4 5 6 7 8 9 def run(): a = f() print(a) 1 def f(): c = 1 return c return 1
函数返回的是值,而不是变量
不是数据格,是数据格里的数据
1 2 3 4 5 6 7 8 9 10 def run(): a = 1 a = f() print(a) def f(): a = 9 return a
上面代码运行完了,你会看到什么
1
9
return
return 有两个效果,
立刻终止当前函数
后面可以跟值,达到返回值效果
也就是说,可以在无返回值函数里,干写一个 return,达到提前结束的效果
1 2 3 4 5 6 7 8 9 10 def run(): f(3) def f(v): if v < 0: return print(v)
返回值 与 None
如果 函数 没有写 return,
或者 写了 return,但是 return 后面没东西
此时,用变量接函数的返回值,会接到 None
1 2 3 4 5 6 7 8 9 10 11 <def run(): result = f(3) print(result) def f(v): if v < 0: return print(v) run()None
元组 与 多返回值
Python 的 元组语法 可以跟 函数结合,
达到多返回值的目的
1 2 3 4 5 6 7 8 9 10 11 < <def run(): a, b = cross(3, 4) print(a) print(b) def cross(a, b): return b, a run()43
函数综合应用
带参数,带返回值的函数
1 2 3 4 5 6 7 8 9 10 def run(): a = 1 a = increase(a) print(a) def increase(a): a += 1 return a
上面代码运行完了,你会看到什么
1
2
挑战
add
写一个函数,算出两个整数的和
max
写一个函数,算出两个整数的最大值
greating
写一个函数,接收一个名字后,控制台打印欢迎 ta 的信息
next
写一个函数,接收一个整数,返回比它大的下一个整数
roll
写一个函数,返回一个 1 - 6 的随机值
random_select
写一个函数,从数组中随机抽选一个值 返回回去
函数对接
一个函数的返回值,可以直接对接另外一个函数的参数
1 2 3 4 5 6 7 8 9 10 def run(): echo(generate()) def generate(): return 1 def echo(value): print(value)
函数调试
样例代码
1 2 3 4 5 6 def filter_out_zeros(values): filtered_values = [] for value in values: if value: filtered_values.append(value) return filtered_values
单元测试
针对一个函数进行测试
1 2 3 4 5 6 7 8 9 10 def run(): # test 1 values = [6, 7, 3, 8, 4] result = filter_out_zeros(values) print(result) # test 2 values = [6, 7, 0, 8, 4] result = filter_out_zeros(values) print(result)
函数下的人工内存
每个函数会 开出自己的新空间
1 2 3 4 5 6 7 8 9 10 11 def run(): values = [6, 7, 3, 8, 4] result = filter_out_zeros(values) print(result) def filter_out_zeros(values): filtered_values = [] for value in values: if value: filtered_values.append(value) return filtered_values
run(): Line Info 2 [6, 7, 3, 8, 4] 3 call filter_out_zeros( [6, 7, 3, 8, 4] ) values filter_out_zeros(): line info 6 [6, 7, 3, 8, 4] 7 | [] 8 | | 6 9 | | | true 10 | [6] | true values filtered_values value ...
debug 工具
跳过 函数
进入 函数
跳出 函数
递归Recursions
什么是
自己调自己
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def run(): values = [6, 7, 3] recursive_print(values, len(values)) def recursive_print(values, length): if length == 0: pass elif length == 1: print(values[length - 1], end="") else: recursive_print(values, length - 1) print("," + str(values[length - 1]), end="") run()
递归下的变量管理
当自己调用自己的时候,等同于开了一个新的同名函数
各自保持自己的变量空间

数据传输
三大传输
赋值
传参
返回值
数据传输下的问题
修改变量
1 2 3 4 5 6 7 8 def run(): a = 1 f(a) print(a) def f(a): a = 2
修改数组变量
1 2 3 4 5 6 7 8 def run(): a = [1, 2] f(a) print(a) def f(a): a = [3, 4]
修改数组变量 里的内容!
1 2 3 4 5 6 7 8 9 def run(): a = [1, 2] f(a) print(a) def f(a): a[0] = 3 a[1] = 4
注意:使用 中括号语法,会让 a 变量产生迷幻的同步效果