Python函数深度解析:从基础到高级装饰器

在Python编程中,函数就像乐高积木------你可以创建小块的功能模块,然后将它们组合成复杂的结构。今天,让我们深入探索Python函数的方方面面,从最基础的函数定义到高级的装饰器模式。

引入:为什么函数如此重要?

想象一下,你正在编写一个数据分析程序:

  • 需要多次计算数据的平均值
  • 需要格式化输出结果
  • 需要验证输入数据的有效性

如果没有函数,你会重复写相同的代码。而使用函数,就像拥有一个魔法工具箱,每个工具都有特定的用途,可以反复使用,让代码更简洁、更易维护。

一、函数基础:构建代码模块

1.1 函数的定义与调用

python 复制代码
# 函数基础:定义、调用、返回值
print("=== Python函数基础 ===\n")

# 1. 最简单的函数
def greet():
    """一个简单的问候函数"""
    print("你好!")
    print("欢迎学习Python函数")

# 调用函数
greet()

# 2. 带参数的函数
def personalized_greet(name):
    """向特定的人问好"""
    print(f"你好,{name}!")
    print(f"{name},今天过得怎么样?")

# 调用带参数的函数
personalized_greet("小明")
personalized_greet("小红")

# 3. 带返回值的函数
def add_numbers(a, b):
    """返回两个数的和"""
    result = a + b
    return result

# 使用返回值
sum_result = add_numbers(5, 3)
print(f"5 + 3 = {sum_result}")

# 返回值可以直接使用
print(f"10 + 20 = {add_numbers(10, 20)}")

# 4. 多个返回值
def get_student_info():
    """返回学生的姓名、年龄和成绩"""
    name = "张三"
    age = 18
    scores = [85, 92, 78]
    return name, age, scores  # 实际上返回一个元组

# 接收多个返回值
student_name, student_age, student_scores = get_student_info()
print(f"学生信息:{student_name},{student_age}岁,成绩:{student_scores}")

# 5. 查看函数信息
print(f"\n函数文档:{add_numbers.__doc__}")
print(f"函数名:{add_numbers.__name__}")
print(f"模块:{add_numbers.__module__}")

1.2 参数传递的四种方式

python 复制代码
print("\n=== 参数传递的四种方式 ===\n")

# 1. 位置参数(最基本的参数传递)
def describe_pet(animal_type, pet_name):
    """显示宠物的信息"""
    print(f"我有一只{animal_type},它叫{pet_name}。")

describe_pet("狗", "旺财")  # 参数按位置传递
describe_pet("猫", "咪咪")

# 2. 关键字参数(指定参数名)
describe_pet(animal_type="仓鼠", pet_name="吱吱")  # 明确指定参数名
describe_pet(pet_name="花花", animal_type="鸟")    # 顺序可以改变

# 3. 默认参数(参数有默认值)
def make_coffee(size="中杯", coffee_type="拿铁", sugar=True):
    """制作咖啡"""
    sugar_text = "加糖" if sugar else "不加糖"
    print(f"制作一杯{size}{coffee_type},{sugar_text}")

make_coffee()                          # 使用所有默认值
make_coffee("大杯")                     # 只指定第一个参数
make_coffee(coffee_type="美式", sugar=False)  # 指定部分参数

# 4. 可变参数(参数数量可变)
def calculate_average(*scores):
    """计算平均分,可以接受任意数量的分数"""
    if len(scores) == 0:
        return 0
    total = sum(scores)
    return total / len(scores)

print(f"平均分1:{calculate_average(85, 90, 78):.2f}")
print(f"平均分2:{calculate_average(92, 88, 95, 76):.2f}")
print(f"平均分3:{calculate_average(100, 95):.2f}")

# 5. 关键字可变参数(**kwargs)
def build_profile(first, last, **user_info):
    """创建一个包含用户所有信息的字典"""
    profile = {}
    profile['first_name'] = first
    profile['last_name'] = last
    for key, value in user_info.items():
        profile[key] = value
    return profile

user_profile = build_profile('张', '三', age=25, city='北京', job='工程师')
print(f"\n用户档案:{user_profile}")

# 6. 参数组合使用(完整的函数签名)
def complex_function(a, b, *args, c=10, d=20, **kwargs):
    """演示所有参数类型的组合"""
    print(f"a={a}, b={b}, args={args}, c={c}, d={d}, kwargs={kwargs}")

# 调用示例
complex_function(1, 2, 3, 4, 5, c=30, e=100, f=200)

二、函数进阶:作用域与闭包

2.1 变量作用域

python 复制代码
print("=== 变量作用域:理解Python的命名空间 ===\n")

# 全局变量(在整个文件中都有效)
global_var = "我是全局变量"

def scope_demo():
    """演示变量作用域"""
    # 局部变量(只在函数内部有效)
    local_var = "我是局部变量"
    
    # 可以在函数内部访问全局变量
    print(f"函数内访问全局变量:{global_var}")
    print(f"函数内访问局部变量:{local_var}")
    
    # 修改全局变量需要使用global关键字
    global global_var
    global_var = "全局变量已被修改"
    
    # 嵌套作用域
    def inner_function():
        # 内层函数可以访问外层函数的变量
        inner_var = "我是内层局部变量"
        print(f"\n内层函数:")
        print(f"  访问外层局部变量:{local_var}")
        print(f"  访问全局变量:{global_var}")
        print(f"  访问内层局部变量:{inner_var}")
        
        # 使用nonlocal修改外层函数的变量
        nonlocal local_var
        local_var = "外层局部变量已被内层函数修改"
    
    inner_function()
    print(f"\n外层函数修改后:local_var = {local_var}")

# 函数调用
print(f"函数调用前全局变量:{global_var}")
scope_demo()
print(f"函数调用后全局变量:{global_var}")

# 尝试访问局部变量(会报错)
try:
    print(local_var)
except NameError as e:
    print(f"\n错误:{e} - 不能从外部访问局部变量")

print("\n=== 作用域查找规则:LEGB ===")
print("1. Local(局部作用域) - 函数内部")
print("2. Enclosing(嵌套作用域) - 外层函数")
print("3. Global(全局作用域) - 模块级别")
print("4. Built-in(内置作用域) - Python内置函数和变量")

2.2 闭包:函数中的函数

python 复制代码
print("\n=== 闭包:函数返回函数 ===")

# 闭包:函数内部定义了另一个函数,并且内部函数引用了外部函数的变量
def outer_function(message):
    """外部函数"""
    def inner_function():
        """内部函数(闭包)"""
        print(f"消息:{message}")
    return inner_function  # 返回内部函数,而不是调用它

# 创建闭包
closure = outer_function("你好,闭包!")
closure()  # 调用闭包函数

print("\n=== 闭包的实际应用:计数器 ===")

def create_counter():
    """创建一个计数器闭包"""
    count = 0  # 这个变量会被闭包"记住"
    
    def counter():
        nonlocal count  # 声明使用外层函数的变量
        count += 1
        return count
    
    return counter

# 创建两个独立的计数器
counter1 = create_counter()
counter2 = create_counter()

print(f"计数器1:{counter1()}")  # 1
print(f"计数器1:{counter1()}")  # 2
print(f"计数器2:{counter2()}")  # 1
print(f"计数器1:{counter1()}")  # 3
print(f"计数器2:{counter2()}")  # 2

print("\n=== 闭包应用:函数工厂 ===")

def power_factory(exponent):
    """创建计算幂的函数工厂"""
    def power(base):
        return base ** exponent
    return power

# 创建不同的幂函数
square = power_factory(2)  # 平方函数
cube = power_factory(3)    # 立方函数

print(f"3的平方:{square(3)}")  # 9
print(f"3的立方:{cube(3)}")    # 27
print(f"5的平方:{square(5)}")  # 25

print("\n=== 闭包应用:配置函数 ===")

def make_multiplier(factor):
    """创建乘以特定因子的函数"""
    def multiplier(x):
        return x * factor
    return multiplier

# 创建不同的乘法器
double = make_multiplier(2)
triple = make_multiplier(3)
ten_times = make_multiplier(10)

print(f"2倍:{double(5)}")      # 10
print(f"3倍:{triple(5)}")      # 15
print(f"10倍:{ten_times(5)}")   # 50

三、装饰器:函数的"化妆师"

3.1 装饰器基础

python 复制代码
print("=== 装饰器基础:增强函数功能 ===")

# 装饰器本质上是一个函数,它接受一个函数作为参数,返回一个新的函数
def simple_decorator(func):
    """一个简单的装饰器"""
    def wrapper():
        print("装饰器:函数执行前")
        result = func()
        print("装饰器:函数执行后")
        return result
    return wrapper

@simple_decorator
def say_hello():
    """被装饰的函数"""
    print("你好,世界!")

# 调用被装饰的函数
print("调用被装饰的函数:")
say_hello()

print("\n=== 手动应用装饰器 ===")

def greet():
    """普通函数"""
    print("你好!")

# 不适用@语法,手动装饰
decorated_greet = simple_decorator(greet)
print("手动装饰的函数:")
decorated_greet()

print("\n=== 带参数的函数装饰 ===")

def logger_decorator(func):
    """记录函数调用的装饰器"""
    def wrapper(*args, **kwargs):
        print(f"调用函数:{func.__name__}")
        print(f"参数:args={args}, kwargs={kwargs}")
        result = func(*args, **kwargs)
        print(f"返回值:{result}")
        return result
    return wrapper

@logger_decorator
def add(a, b):
    """两个数相加"""
    return a + b

@logger_decorator
def greet_person(name, title="先生"):
    """问候某人"""
    return f"你好,{name}{title}!"

# 测试带参数的装饰器
print("测试加法函数:")
result = add(3, 5)
print(f"最终结果:{result}\n")

print("测试问候函数:")
greeting = greet_person("小明", title="同学")
print(f"最终问候:{greeting}")

3.2 实用的装饰器示例

python 复制代码
print("\n=== 实用装饰器示例 ===")

import time
import functools

# 1. 计时装饰器
def timer_decorator(func):
    """计算函数执行时间的装饰器"""
    @functools.wraps(func)  # 保留原函数的元数据
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 执行时间:{end_time - start_time:.4f}秒")
        return result
    return wrapper

@timer_decorator
def slow_function(seconds):
    """模拟耗时操作"""
    time.sleep(seconds)
    return f"等待了{seconds}秒"

print("计时装饰器测试:")
print(slow_function(1))

# 2. 缓存装饰器(记忆化)
def cache_decorator(func):
    """缓存函数结果的装饰器"""
    cache = {}
    
    @functools.wraps(func)
    def wrapper(*args):
        if args in cache:
            print(f"缓存命中:{args} -> {cache[args]}")
            return cache[args]
        result = func(*args)
        cache[args] = result
        print(f"缓存未命中,计算结果:{args} -> {result}")
        return result
    
    return wrapper

@cache_decorator
def fibonacci(n):
    """计算斐波那契数列(递归实现)"""
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print("\n缓存装饰器测试(斐波那契数列):")
print(f"fibonacci(5) = {fibonacci(5)}")
print(f"fibonacci(5) = {fibonacci(5)}")  # 第二次调用应该从缓存获取

# 3. 重试装饰器
def retry_decorator(max_attempts=3, delay=1):
    """重试装饰器,失败时自动重试"""
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            last_exception = None
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    last_exception = e
                    if attempt < max_attempts - 1:
                        print(f"第{attempt+1}次尝试失败:{e},{delay}秒后重试...")
                        time.sleep(delay)
            print(f"所有{max_attempts}次尝试都失败了")
            raise last_exception
        return wrapper
    return decorator

@retry_decorator(max_attempts=3, delay=1)
def unreliable_function():
    """有时会失败的函数"""
    import random
    if random.random() < 0.7:  # 70%的几率失败
        raise ValueError("随机失败")
    return "成功!"

print("\n重试装饰器测试:")
try:
    result = unreliable_function()
    print(f"结果:{result}")
except Exception as e:
    print(f"最终失败:{e}")

3.3 带参数的装饰器

python 复制代码
print("\n=== 带参数的装饰器 ===")

def repeat_decorator(num_times):
    """重复执行函数的装饰器"""
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            results = []
            for i in range(num_times):
                print(f"第{i+1}次执行:")
                result = func(*args, **kwargs)
                results.append(result)
            return results
        return wrapper
    return decorator

@repeat_decorator(num_times=3)
def greet(name):
    """问候函数"""
    return f"你好,{name}!"

print("带参数的装饰器测试:")
results = greet("小明")
print(f"所有结果:{results}")

print("\n=== 多个装饰器 ===")

def decorator1(func):
    def wrapper():
        print("装饰器1:之前")
        func()
        print("装饰器1:之后")
    return wrapper

def decorator2(func):
    def wrapper():
        print("装饰器2:之前")
        func()
        print("装饰器2:之后")
    return wrapper

@decorator1
@decorator2
def say_hi():
    print("你好!")

print("多个装饰器测试:")
say_hi()
print("\n注意:装饰器的应用顺序是从下往上(从里到外)")

四、Lambda函数与高阶函数

4.1 Lambda表达式

python 复制代码
print("=== Lambda表达式:匿名函数 ===")

# Lambda表达式用于创建简单的匿名函数
# 语法:lambda 参数: 表达式

# 1. 基本用法
square = lambda x: x ** 2
print(f"平方函数:square(5) = {square(5)}")

add = lambda a, b: a + b
print(f"加法函数:add(3, 4) = {add(3, 4)}")

# 2. 立即调用
result = (lambda x, y: x * y)(3, 4)
print(f"立即调用:(lambda x, y: x * y)(3, 4) = {result}")

# 3. 在列表推导式中使用
numbers = [1, 2, 3, 4, 5]
squares = [(lambda x: x ** 2)(x) for x in numbers]
print(f"列表推导式中的Lambda:{squares}")

print("\n=== Lambda的典型应用场景 ===")

# 1. 排序
students = [
    {"name": "小明", "score": 85},
    {"name": "小红", "score": 92},
    {"name": "小刚", "score": 78}
]

# 按分数排序
students_sorted = sorted(students, key=lambda s: s["score"], reverse=True)
print("按分数排序:")
for student in students_sorted:
    print(f"  {student['name']}: {student['score']}分")

# 2. 过滤
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(f"\n偶数:{even_numbers}")

# 3. 映射
squared_numbers = list(map(lambda x: x ** 2, numbers))
print(f"平方数:{squared_numbers}")

# 4. 在GUI编程中(如按钮回调)
print("\nLambda作为回调函数的示例:")
def button_click(button_name):
    return lambda: print(f"{button_name} 被点击了")

ok_button = button_click("确定")
cancel_button = button_click("取消")

# 模拟点击
ok_button()
cancel_button()

4.2 高阶函数

python 复制代码
print("\n=== 高阶函数:函数作为参数或返回值 ===")

# 1. 函数作为参数
def apply_operation(numbers, operation):
    """对列表中的每个数应用操作"""
    return [operation(x) for x in numbers]

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

def square(x):
    return x ** 2

def double(x):
    return x * 2

print(f"应用平方操作:{apply_operation(numbers, square)}")
print(f"应用加倍操作:{apply_operation(numbers, double)}")
print(f"应用Lambda操作:{apply_operation(numbers, lambda x: x + 10)}")

# 2. 函数作为返回值
def make_adder(n):
    """创建加法函数"""
    def adder(x):
        return x + n
    return adder

add5 = make_adder(5)
add10 = make_adder(10)

print(f"add5(3) = {add5(3)}")
print(f"add10(3) = {add10(3)}")

# 3. 函数组合
def compose(f, g):
    """组合两个函数:f(g(x))"""
    return lambda x: f(g(x))

def add_one(x):
    return x + 1

def multiply_by_two(x):
    return x * 2

# 创建组合函数:先加1,再乘以2
add_then_multiply = compose(multiply_by_two, add_one)
print(f"add_then_multiply(3) = {add_then_multiply(3)}")  # (3+1)*2 = 8

# 4. 部分函数
from functools import partial

def power(base, exponent):
    """计算幂"""
    return base ** exponent

# 创建平方函数(固定exponent为2)
square = partial(power, exponent=2)
print(f"square(5) = {square(5)}")

# 创建立方函数(固定exponent为3)
cube = partial(power, exponent=3)
print(f"cube(3) = {cube(3)}")

五、生成器函数:惰性计算的艺术

5.1 yield关键字与生成器

python 复制代码
print("=== 生成器函数:使用yield ===")

# 生成器函数使用yield返回一个值,并暂停执行,下次从暂停处继续
def simple_generator():
    """一个简单的生成器"""
    print("开始")
    yield 1
    print("继续")
    yield 2
    print("结束")
    yield 3

print("创建生成器:")
gen = simple_generator()

print("第一次调用next:")
print(next(gen))

print("第二次调用next:")
print(next(gen))

print("第三次调用next:")
print(next(gen))

# 再次调用会抛出StopIteration异常
try:
    print(next(gen))
except StopIteration:
    print("生成器已结束")

print("\n=== 使用for循环遍历生成器 ===")

def countdown(n):
    """倒数生成器"""
    while n > 0:
        yield n
        n -= 1

print("倒数:")
for number in countdown(5):
    print(f"倒计时:{number}")

print("\n=== 生成器表达式 ===")

# 生成器表达式类似于列表推导式,但使用圆括号
numbers = [1, 2, 3, 4, 5]

# 列表推导式:立即计算所有值
squares_list = [x**2 for x in numbers]
print(f"列表推导式:{squares_list},类型:{type(squares_list)}")

# 生成器表达式:惰性计算
squares_gen = (x**2 for x in numbers)
print(f"生成器表达式:{squares_gen},类型:{type(squares_gen)}")
print(f"转换为列表:{list(squares_gen)}")

5.2 生成器的实际应用

python 复制代码
print("\n=== 生成器的实际应用 ===")

# 1. 读取大文件
def read_large_file(file_path):
    """逐行读取大文件"""
    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            yield line.strip()

# 模拟大文件
with open('large_file.txt', 'w', encoding='utf-8') as f:
    for i in range(1000):
        f.write(f"这是第{i+1}行数据\n")

print("读取大文件(不占用太多内存):")
line_count = 0
for line in read_large_file('large_file.txt'):
    if line_count < 5:  # 只显示前5行
        print(f"  {line}")
    line_count += 1
print(f"总行数:{line_count}")

# 2. 无限序列
def fibonacci_sequence():
    """生成斐波那契数列(无限)"""
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

print("\n斐波那契数列(前10个):")
fib_gen = fibonacci_sequence()
for i in range(10):
    print(f"  F{i} = {next(fib_gen)}")

# 3. 管道处理
def number_generator(n):
    """生成数字"""
    for i in range(n):
        yield i

def square_numbers(numbers):
    """平方数字"""
    for num in numbers:
        yield num ** 2

def filter_even(numbers):
    """过滤偶数"""
    for num in numbers:
        if num % 2 == 0:
            yield num

print("\n管道处理:生成 → 平方 → 过滤")
pipeline = filter_even(square_numbers(number_generator(10)))
print(f"结果:{list(pipeline)}")

# 4. 协程(双向通信)
def coroutine_example():
    """一个简单的协程"""
    print("协程启动")
    while True:
        value = yield  # 接收值
        print(f"收到值:{value}")
        yield value * 2  # 返回值

print("\n协程示例:")
coro = coroutine_example()
next(coro)  # 启动协程,执行到第一个yield
print(f"发送10,收到:{coro.send(10)}")
next(coro)  # 继续到下一个yield
print(f"发送20,收到:{coro.send(20)}")

六、面向对象中的函数:方法与特殊方法

6.1 类方法与实例方法

python 复制代码
print("=== 类中的函数:方法 ===")

class Calculator:
    """计算器类"""
    
    # 类属性
    operation_count = 0
    
    def __init__(self, name="计算器"):
        """构造方法"""
        self.name = name
        self.history = []
    
    # 实例方法:操作实例数据
    def add(self, a, b):
        """加法"""
        Calculator.operation_count += 1
        result = a + b
        self.history.append(f"{a} + {b} = {result}")
        return result
    
    def multiply(self, a, b):
        """乘法"""
        Calculator.operation_count += 1
        result = a * b
        self.history.append(f"{a} × {b} = {result}")
        return result
    
    # 实例方法:访问实例数据
    def show_history(self):
        """显示历史记录"""
        if not self.history:
            print(f"{self.name} 还没有操作记录")
        else:
            print(f"{self.name} 的操作记录:")
            for operation in self.history:
                print(f"  {operation}")
    
    # 类方法:操作类数据
    @classmethod
    def get_operation_count(cls):
        """获取总操作次数"""
        return cls.operation_count
    
    # 静态方法:不访问类或实例数据
    @staticmethod
    def help():
        """显示帮助信息"""
        return "这是一个计算器类,支持加法和乘法运算"

print("创建计算器实例:")
calc1 = Calculator("我的计算器")

print("\n使用实例方法:")
print(f"5 + 3 = {calc1.add(5, 3)}")
print(f"5 × 3 = {calc1.multiply(5, 3)}")
calc1.show_history()

print("\n使用类方法:")
print(f"总操作次数:{Calculator.get_operation_count()}")

print("\n使用静态方法:")
print(f"帮助信息:{Calculator.help()}")

print("\n创建第二个计算器:")
calc2 = Calculator("第二个计算器")
print(f"10 + 20 = {calc2.add(10, 20)}")
print(f"总操作次数(类级别):{Calculator.get_operation_count()}")

6.2 特殊方法(魔术方法)

python 复制代码
print("\n=== 特殊方法(魔术方法) ===")

class Vector:
    """向量类,演示特殊方法"""
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    # 字符串表示
    def __str__(self):
        """str() 时调用"""
        return f"Vector({self.x}, {self.y})"
    
    def __repr__(self):
        """repr() 时调用"""
        return f"Vector({self.x}, {self.y})"
    
    # 算术运算
    def __add__(self, other):
        """+ 运算"""
        return Vector(self.x + other.x, self.y + other.y)
    
    def __sub__(self, other):
        """- 运算"""
        return Vector(self.x - other.x, self.y - other.y)
    
    def __mul__(self, scalar):
        """* 运算(向量乘以标量)"""
        return Vector(self.x * scalar, self.y * scalar)
    
    # 比较运算
    def __eq__(self, other):
        """== 运算"""
        return self.x == other.x and self.y == other.y
    
    def __lt__(self, other):
        """< 运算(比较长度)"""
        return (self.x**2 + self.y**2) < (other.x**2 + other.y**2)
    
    # 长度和布尔值
    def __len__(self):
        """len() 时调用(返回维度)"""
        return 2
    
    def __bool__(self):
        """bool() 时调用"""
        return self.x != 0 or self.y != 0
    
    # 调用对象
    def __call__(self, scale=1):
        """对象被调用时"""
        return Vector(self.x * scale, self.y * scale)

print("创建向量:")
v1 = Vector(3, 4)
v2 = Vector(1, 2)

print(f"v1 = {v1}")
print(f"v2 = {v2}")

print(f"\nv1 + v2 = {v1 + v2}")
print(f"v1 - v2 = {v1 - v2}")
print(f"v1 * 2 = {v1 * 2}")

print(f"\nv1 == v2: {v1 == v2}")
print(f"v1 < v2: {v1 < v2}")

print(f"\nlen(v1): {len(v1)}")
print(f"bool(v1): {bool(v1)}")

print(f"\nv1(2): {v1(2)}")  # 调用对象

print("\n=== 属性访问特殊方法 ===")

class Person:
    """演示属性访问特殊方法"""
    
    def __init__(self, name, age):
        self.name = name
        self._age = age  # 私有属性
    
    # 属性访问
    def __getattr__(self, name):
        """访问不存在的属性时调用"""
        print(f"__getattr__: 尝试访问不存在的属性 '{name}'")
        return None
    
    def __setattr__(self, name, value):
        """设置属性时调用"""
        if name == '_age' and value < 0:
            print("年龄不能为负数!")
            return
        print(f"__setattr__: 设置属性 {name} = {value}")
        super().__setattr__(name, value)
    
    def __delattr__(self, name):
        """删除属性时调用"""
        if name == 'name':
            print("不能删除姓名属性!")
            return
        print(f"__delattr__: 删除属性 {name}")
        super().__delattr__(name)

person = Person("小明", 25)
print(f"姓名:{person.name}")
print(f"年龄:{person._age}")

person.salary = 5000  # 设置新属性
print(f"薪水:{person.salary}")

print(f"不存在的属性:{person.address}")  # 访问不存在的属性

del person.salary  # 删除属性
print(f"删除后:{person.salary}")

七、实战应用:函数式数据处理管道

python 复制代码
print("\n=== 实战:函数式数据处理管道 ===")

# 创建示例数据
students = [
    {"name": "张三", "age": 18, "scores": {"math": 85, "english": 92, "chinese": 78}},
    {"name": "李四", "age": 17, "scores": {"math": 92, "english": 88, "chinese": 95}},
    {"name": "王五", "age": 19, "scores": {"math": 76, "english": 85, "chinese": 90}},
    {"name": "赵六", "age": 18, "scores": {"math": 88, "english": 92, "chinese": 86}},
    {"name": "钱七", "age": 17, "scores": {"math": 95, "english": 79, "chinese": 88}},
]

# 1. 纯函数:不修改外部状态,相同输入总是得到相同输出
def calculate_average(student):
    """计算学生的平均分"""
    scores = student["scores"].values()
    return sum(scores) / len(scores)

def add_average(student):
    """添加平均分到学生信息(返回新字典)"""
    student_copy = student.copy()
    student_copy["average"] = calculate_average(student)
    return student_copy

# 2. 高阶函数:处理数据管道
def process_students(students, *processors):
    """处理学生数据管道"""
    result = students
    for processor in processors:
        result = processor(result)
    return result

# 3. 数据处理函数
def add_average_to_all(students):
    """为所有学生添加平均分"""
    return list(map(add_average, students))

def filter_by_age(students, min_age=18):
    """过滤年龄"""
    return list(filter(lambda s: s["age"] >= min_age, students))

def sort_by_average(students, reverse=True):
    """按平均分排序"""
    return sorted(students, key=lambda s: s.get("average", 0), reverse=reverse)

def get_top_n(students, n=3):
    """获取前N名学生"""
    return students[:n]

def format_output(students):
    """格式化输出"""
    return [f"{s['name']}({s['age']}岁): 平均分{s['average']:.1f}" for s in students]

# 4. 组合函数
from functools import partial

# 创建部分函数
filter_adults = partial(filter_by_age, min_age=18)
get_top_3 = partial(get_top_n, n=3)

# 5. 构建数据处理管道
print("数据处理管道:添加平均分 → 过滤成年人 → 按平均分排序 → 取前三名")

result = process_students(
    students,
    add_average_to_all,
    filter_adults,
    lambda s: sort_by_average(s, reverse=True),
    get_top_3,
    format_output
)

print("\n结果:")
for i, student in enumerate(result, 1):
    print(f"  {i}. {student}")

# 6. 使用装饰器记录处理步骤
def log_step(step_name):
    """记录处理步骤的装饰器"""
    def decorator(func):
        def wrapper(students):
            print(f"步骤:{step_name} (处理{len(students)}名学生)")
            result = func(students)
            print(f"  结果:{len(result)}名学生")
            return result
        return wrapper
    return decorator

print("\n=== 带日志的数据处理管道 ===")

@log_step("添加平均分")
def add_average_with_log(students):
    return add_average_to_all(students)

@log_step("过滤成年人")
def filter_adults_with_log(students):
    return filter_adults(students)

@log_step("按平均分排序")
def sort_by_average_with_log(students):
    return sort_by_average(students, reverse=True)

@log_step("取前三名")
def get_top_3_with_log(students):
    return get_top_3(students)

final_result = process_students(
    students,
    add_average_with_log,
    filter_adults_with_log,
    sort_by_average_with_log,
    get_top_3_with_log,
    format_output
)

print("\n最终结果:")
for i, student in enumerate(final_result, 1):
    print(f"  {i}. {student}")

八、总结:Python函数的核心要点

🎯 核心要点总结:

  1. 函数定义 :使用def关键字,可以带参数和返回值

    python 复制代码
    def function_name(parameters):
        """文档字符串"""
        # 函数体
        return value
  2. 四种参数类型

    • 位置参数:按顺序传递
    • 关键字参数:指定参数名
    • 默认参数:参数有默认值
    • 可变参数*args**kwargs
  3. 装饰器:增强函数功能的强大工具

    python 复制代码
    @decorator
    def function():
        pass
  4. Lambda表达式:匿名函数,简洁高效

    python 复制代码
    lambda x: x**2
  5. 生成器 :使用yield,节省内存

    python 复制代码
    def generator():
        yield value
  6. 闭包:函数中的函数,可以"记住"外部变量

💡 最佳实践:

  1. 一个函数只做一件事:保持函数简洁,功能单一

  2. 使用有意义的函数名:函数名应该描述函数的功能

  3. 编写文档字符串:解释函数的作用、参数和返回值

  4. 使用类型提示(Python 3.5+):提高代码可读性

    python 复制代码
    def add(a: int, b: int) -> int:
        return a + b
  5. 避免副作用:纯函数更容易测试和维护

相关推荐
抹除不掉的轻狂丶2 小时前
Java 日志框架完整指南:发展历史、核心组成与最佳实践
java·开发语言·python
目标是分享一切2 小时前
python卸载的时候出现0x80070643如何解决
python
Mqh1807622 小时前
day48 Tensorboard
python
tangjunjun-owen2 小时前
DINOv3 demo
python·深度学习·机器学习
IT北辰2 小时前
用 Python 自动解析药品规格并计算包装总容量 —— pandas + 正则实战
开发语言·python·pandas
python机器学习ML3 小时前
论文复现-以动物图像分类为例进行多模型性能对比分析
人工智能·python·神经网络·机器学习·计算机视觉·scikit-learn·sklearn
沃斯堡&蓝鸟3 小时前
DAY30 函数专题1:函数定义与参数
python
小oo呆3 小时前
【学习心得】Python的TypedDict(简介)
开发语言·python
文洪涛3 小时前
VS Code Python “第一次运行失败 / 先执行 python 再激活 Conda” 问题定位与解决
开发语言·python·conda