课程 8:Python 中的函数

📚 课程目录

函数编程简介:
函数是Python编程的核心概念,它允许我们将代码组织成可重用的块。函数不仅可以提高代码的可读性和维护性,还能实现代码的模块化和复用。本课程将系统学习Python函数的定义、调用、参数传递、返回值等核心概念。

1. 函数基础概念

1.1 什么是函数

函数是一段可重用的代码块,它接受输入(参数),执行特定的操作,并返回结果。函数的主要作用是:

1.2 函数的基本结构

def function_name(parameters):
    """文档字符串:描述函数的功能"""
    # 函数体:具体的代码逻辑
    return result  # 返回值(可选)

🔍 函数结构说明

2. 函数定义与调用

2.1 简单函数示例

# 定义一个简单的问候函数
def greet():
    """打印问候语"""
    print("Hello, World!")

# 调用函数
greet()  # 输出: Hello, World!

2.2 带参数的函数

# 带参数的函数
def greet_person(name):
    """向指定的人打招呼"""
    print(f"Hello, {name}!")

# 调用函数
greet_person("Alice")  # 输出: Hello, Alice!
greet_person("Bob")    # 输出: Hello, Bob!

2.3 带返回值的函数

# 计算两个数的和
def add_numbers(a, b):
    """计算两个数的和"""
    result = a + b
    return result

# 调用函数并获取返回值
sum_result = add_numbers(5, 3)
print(sum_result)  # 输出: 8

# 直接在表达式中使用函数
print(add_numbers(10, 20))  # 输出: 30

3. 函数参数详解

3.1 位置参数

def describe_person(name, age, city):
    """描述一个人的基本信息"""
    print(f"{name} is {age} years old and lives in {city}.")

# 按位置传递参数
describe_person("Alice", 25, "Beijing")
# 输出: Alice is 25 years old and lives in Beijing.

3.2 关键字参数

# 使用关键字参数,顺序可以改变
describe_person(age=30, name="Bob", city="Shanghai")
# 输出: Bob is 30 years old and lives in Shanghai.

3.3 默认参数

def greet_with_title(name, title="Mr."):
    """带默认参数的问候函数"""
    print(f"Hello, {title} {name}!")

# 使用默认参数
greet_with_title("Smith")  # 输出: Hello, Mr. Smith!

# 覆盖默认参数
greet_with_title("Johnson", "Dr.")  # 输出: Hello, Dr. Johnson!

3.4 可变参数

# *args:接收任意数量的位置参数
def sum_all(*args):
    """计算所有参数的和"""
    total = 0
    for num in args:
        total += num
    return total

print(sum_all(1, 2, 3, 4, 5))  # 输出: 15
print(sum_all(10, 20))         # 输出: 30

# **kwargs:接收任意数量的关键字参数
def print_info(**kwargs):
    """打印所有关键字参数"""
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25, city="Beijing")
# 输出:
# name: Alice
# age: 25
# city: Beijing

4. 返回值详解

4.1 基本返回值

def get_square(x):
    """返回一个数的平方"""
    return x ** 2

result = get_square(5)
print(result)  # 输出: 25

4.2 多个返回值

def get_min_max(numbers):
    """返回列表中的最小值和最大值"""
    if not numbers:
        return None, None
    return min(numbers), max(numbers)

min_val, max_val = get_min_max([3, 1, 4, 1, 5, 9, 2, 6])
print(f"最小值: {min_val}, 最大值: {max_val}")
# 输出: 最小值: 1, 最大值: 9

4.3 条件返回值

def check_number(num):
    """检查数字的性质"""
    if num > 0:
        return "正数"
    elif num < 0:
        return "负数"
    else:
        return "零"

print(check_number(5))   # 输出: 正数
print(check_number(-3))  # 输出: 负数
print(check_number(0))   # 输出: 零

5. 变量作用域

5.1 局部变量与全局变量

# 全局变量
global_var = "我是全局变量"

def test_scope():
    # 局部变量
    local_var = "我是局部变量"
    print(f"函数内访问全局变量: {global_var}")
    print(f"函数内访问局部变量: {local_var}")

test_scope()
print(f"函数外访问全局变量: {global_var}")
# print(local_var)  # 错误!局部变量在函数外不可访问

5.2 global关键字

counter = 0

def increment_counter():
    global counter  # 声明使用全局变量
    counter += 1
    print(f"计数器: {counter}")

increment_counter()  # 输出: 计数器: 1
increment_counter()  # 输出: 计数器: 2
increment_counter()  # 输出: 计数器: 3

6. 函数的高级特性

6.1 lambda函数(匿名函数)

# 普通函数
def square(x):
    return x ** 2

# 等价的lambda函数
square_lambda = lambda x: x ** 2

print(square(5))        # 输出: 25
print(square_lambda(5)) # 输出: 25

# lambda函数常用于排序
names = ["Alice", "Bob", "Charlie", "David"]
sorted_names = sorted(names, key=lambda name: len(name))
print(sorted_names)  # 输出: ['Bob', 'Alice', 'David', 'Charlie']

6.2 函数作为参数

def apply_operation(func, x, y):
    """应用指定的操作函数"""
    return func(x, y)

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

def multiply(a, b):
    return a * b

# 传递函数作为参数
result1 = apply_operation(add, 5, 3)
result2 = apply_operation(multiply, 5, 3)

print(result1)  # 输出: 8
print(result2)  # 输出: 15

6.3 嵌套函数

def outer_function(x):
    """外部函数"""
    def inner_function(y):
        """内部函数"""
        return x + y  # 可以访问外部函数的变量
    return inner_function

# 创建闭包
add_five = outer_function(5)
result = add_five(3)
print(result)  # 输出: 8

6.4 函数注解(类型提示)

为什么使用类型提示?

# 基本类型提示
def greet(name: str) -> None:
    print(f"Hello, {name}!")

def add(a: int, b: int) -> int:
    return a + b

# 组合类型与可选类型
from typing import Optional, List, Dict, Tuple, Union

def find_user_age(users: Dict[str, int], name: str) -> Optional[int]:
    return users.get(name)

def average(scores: List[float]) -> float:
    return sum(scores) / len(scores) if scores else 0.0

def parse_pair(text: str) -> Tuple[str, int]:
    name, num = text.split(":")
    return name, int(num)

def to_str(value: Union[int, float, bool]) -> str:
    return str(value)

# 注意:类型提示在运行时不强制检查,主要用于静态分析
greet("Alice")
print(add(3, 5))
print(find_user_age({"Alice": 23}, "Bob"))  # 输出: None

7. 函数编程最佳实践

7.1 函数命名规范

7.2 文档字符串规范

def calculate_area(length, width):
    """
    计算矩形的面积
    
    参数:
        length (float): 矩形的长度
        width (float): 矩形的宽度
    
    返回:
        float: 矩形的面积
    
    示例:
        >>> calculate_area(5.0, 3.0)
        15.0
    """
    return length * width

7.3 错误处理

def safe_divide(a, b):
    """安全除法函数"""
    try:
        return a / b
    except ZeroDivisionError:
        print("错误:除数不能为零")
        return None
    except TypeError:
        print("错误:参数类型不正确")
        return None

# 测试错误处理
print(safe_divide(10, 2))   # 输出: 5.0
print(safe_divide(10, 0))   # 输出: 错误:除数不能为零
print(safe_divide("10", 2)) # 输出: 错误:参数类型不正确

函数编程要点总结