返回课程目录

第 04 章 函数与代码复用

学习目标

  • 定义、调用函数并接收返回值。
  • 使用位置参数、可选参数和参数名称传递。
  • 区分局部变量与全局变量。
  • 编写具有基例和递归关系的递归函数。

1. 定义和调用

def average(a, b):
    return (a + b) / 2

result = average(80, 96)
print(result)

def 是定义函数的保留字,函数名后使用括号和冒号。return 把结果返回给调用处;没有 return 的函数返回 None。

2. 参数传递

def power(base, exponent=2):
    return base ** exponent

print(power(5))
print(power(5, 3))
print(power(exponent=4, base=2))

输出:

25
125
16

第二个参数有默认值,调用时可以省略。使用参数名称时可以改变传递顺序。每次调用都可以传入不同的参数,不要求参数永远相同。

3. 变量作用域

函数内部赋值的变量是局部变量:

count = 10

def increase():
    count = 1
    return count

print(increase())
print(count)

输出:

1
10

函数中的赋值没有修改外部 count。必须修改全局变量时使用 global:

count = 10

def increase():
    global count
    count += 1

increase()
print(count)

输出为 11。能用参数和返回值解决时,应优先避免全局变量。

4. 代码复用

把重复操作放入函数,可以减少重复代码:

def rectangle_area(length, width):
    return length * width

print(rectangle_area(5, 3))
print(rectangle_area(8, 4))

5. 递归

递归函数在定义中调用自身,并且必须有能够停止的基例。

def factorial(n):
    if n == 0 or n == 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))

计算过程是 5 * 4 * 3 * 2 * 1,结果为 120。

def fibonacci(n):
    if n == 0 or n == 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

默认递归深度约为 1000 层,超过后解释器终止程序。递归可以有多个基例,例如阶乘中的 0 和 1。

本章练习

  • 编写 max_value(a, b),返回较大值。
  • 给函数增加默认参数,使税率默认为 0.06。
  • 用递归计算正整数各位数字之和。
  • 判断一个函数没有 return 时,调用结果是什么。

本章小结

  • def 定义函数,return 返回结果。
  • 默认参数可以省略,参数名称可以改变传递顺序。
  • 函数内赋值默认形成局部变量,global 才修改全局变量。
  • 递归必须包含基例,并使每次调用更接近基例。