跳转至

第六章:函数

函数是组织好的、可重复使用的代码块。

6.1 函数定义

基本语法

def greet():
    """打招呼函数"""
    print("Hello!")

# 调用函数
greet()

带参数的函数

def greet(name):
    print(f"Hello, {name}!")

greet("张三")  # Hello, 张三!

带返回值的函数

def add(a, b):
    return a + b

result = add(3, 5)
print(result)  # 8

多个返回值

def get_info():
    name = "张三"
    age = 25
    return name, age

name, age = get_info()
print(name, age)  # 张三 25

6.2 参数类型

位置参数

def greet(name, age):
    print(f"{name} 今年 {age} 岁")

greet("张三", 25)  # 按顺序传递

关键字参数

def greet(name, age):
    print(f"{name} 今年 {age} 岁")

greet(age=25, name="张三")  # 指定参数名
greet("张三", age=25)       # 混合使用

默认参数

def greet(name, greeting="你好"):
    print(f"{greeting}, {name}!")

greet("张三")           # 你好, 张三!
greet("张三", "早上好")  # 早上好, 张三!

可变位置参数 *args

def add(*numbers):
    total = 0
    for num in numbers:
        total += num
    return total

print(add(1, 2, 3))      # 6
print(add(1, 2, 3, 4, 5)) # 15

可变关键字参数 **kwargs

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="张三", age=25, city="北京")
# name: 张三
# age: 25
# city: 北京

参数顺序

def func(a, b, *args, c=10, d=20, **kwargs):
    """
    参数顺序:
    1. 位置参数
    2. 可变位置参数 *args
    3. 默认参数
    4. 可变关键字参数 **kwargs
    """
    print(a, b, args, c, d, kwargs)

func(1, 2, 3, 4, c=30, e=50)
# 1 2 (3, 4) 30 20 {'e': 50}

6.3 文档字符串

def calculate_bmi(weight, height):
    """
    计算 BMI 指数

    参数:
        weight: 体重(公斤)
        height: 身高(米)

    返回:
        BMI 指数

    示例:
        >>> calculate_bmi(70, 1.75)
        22.86
    """
    bmi = weight / (height ** 2)
    return round(bmi, 2)

# 查看文档
print(calculate_bmi.__doc__)
help(calculate_bmi)

6.4 变量作用域

局部变量

def my_func():
    x = 10  # 局部变量
    print(x)

my_func()
# print(x)  # NameError: x 未定义

全局变量

x = 10  # 全局变量

def my_func():
    print(x)  # 可以访问

my_func()  # 10
print(x)    # 10

global 关键字

x = 10

def my_func():
    global x
    x = 20  # 修改全局变量

my_func()
print(x)  # 20

nonlocal 关键字

def outer():
    x = 10

    def inner():
        nonlocal x
        x = 20  # 修改外层函数的变量

    inner()
    print(x)  # 20

outer()

6.5 匿名函数 lambda

基本语法

# 普通函数
def add(a, b):
    return a + b

# lambda 表达式
add = lambda a, b: a + b

print(add(3, 5))  # 8

常见用法

# 作为参数传递
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, numbers))
print(squares)  # [1, 4, 9, 16, 25]

# 过滤
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4]

# 排序
students = [("张三", 85), ("李四", 92), ("王五", 78)]
students.sort(key=lambda x: x[1], reverse=True)
print(students)  # [('李四', 92), ('张三', 85), ('王五', 78)]

6.6 高阶函数

map()

numbers = [1, 2, 3, 4, 5]

# 对每个元素应用函数
squares = list(map(lambda x: x**2, numbers))
print(squares)  # [1, 4, 9, 16, 25]

# 多个序列
a = [1, 2, 3]
b = [4, 5, 6]
sums = list(map(lambda x, y: x + y, a, b))
print(sums)  # [5, 7, 9]

filter()

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 过滤偶数
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4, 6, 8, 10]

reduce()

from functools import reduce

numbers = [1, 2, 3, 4, 5]

# 累加
total = reduce(lambda x, y: x + y, numbers)
print(total)  # 15

# 阶乘
factorial = reduce(lambda x, y: x * y, range(1, 6))
print(factorial)  # 120

sorted()

students = [
    {"name": "张三", "score": 85},
    {"name": "李四", "score": 92},
    {"name": "王五", "score": 78}
]

# 按分数排序
sorted_students = sorted(students, key=lambda x: x["score"], reverse=True)
print(sorted_students)

6.7 装饰器

装饰器是修改函数行为的函数。

基本装饰器

def my_decorator(func):
    def wrapper():
        print("函数执行前")
        func()
        print("函数执行后")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()
# 函数执行前
# Hello!
# 函数执行后

带参数的装饰器

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("函数执行前")
        result = func(*args, **kwargs)
        print("函数执行后")
        return result
    return wrapper

@my_decorator
def add(a, b):
    return a + b

result = add(3, 5)
print(result)

实用装饰器示例

import time

def timer(func):
    """计算函数执行时间"""
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} 执行时间: {end - start:.2f}秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)
    return "完成"

slow_function()
# slow_function 执行时间: 1.00秒

6.8 递归函数

函数调用自身。

阶乘

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

print(factorial(5))  # 120

斐波那契数列

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

# 打印前 10 项
for i in range(10):
    print(fibonacci(i), end=" ")
# 0 1 1 2 3 5 8 13 21 34

小结

本章学习了:

  • ✅ 函数定义和调用
  • ✅ 参数类型
  • ✅ 变量作用域
  • ✅ lambda 表达式
  • ✅ 高阶函数
  • ✅ 装饰器
  • ✅ 递归函数

下一章

第七章:面向对象 - 学习类和对象。

练习

  1. 编写函数判断一个数是否为回文数。
  2. 使用装饰器实现函数缓存(记忆化)。
  3. 编写递归函数计算列表元素之和。