函数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)

你会看见什么

A

2 1

B

2 2

规则

每个函数有自己的数据空间,用于存储变量,且相互独立

函数间的数据传输

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

函数级别的 IO专业名词数据传输方向
输入参数从 外面 进入到 函数里
输出返回值从 函数里 流出到 外面

函数调用的完整生命周期

1.

调用前

2.

开始调用 f,准备变量空间

调用 f 时,为 被调用函数 f,开启单独变量空间

run 可使用 参数 将一些值 带到 函数 f的 新的变量空间

3.

运行 被调用函数 f

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

4.

被调用函数 f 执行结束,准备返回

有些函数有返回值,此时会带着返回值 回到 刚才的函数 run

5.

调用结束,销毁函数 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()
上面代码运行完了,你会看到什么
A

1

B

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()
上面代码运行完了,你会看到什么
A

1, 2

B

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()
上面代码运行完了,你会看到什么
A

1, 2

B

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
上面代码运行完了,你会看到什么
A

1

B

9

return

return 有两个效果,

1.

立刻终止当前函数

2.

后面可以跟值,达到返回值效果

也就是说,可以在无返回值函数里,干写一个 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
上面代码运行完了,你会看到什么
A

1

B

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.

返回值

数据传输下的问题

修改变量
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 变量产生迷幻的同步效果

ZZAX 微信公众

文档一更新,立刻告诉你