Python 函数

0 阅读16分钟

Python 函数

目录


函数基础

定义和调用函数

# 定义函数
def greet():
    print("Hello, World!")

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

带参数的函数

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

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

文档字符串(Docstring)

def add(a, b):
    """
    计算两个数的和

    参数:
        a: 第一个数
        b: 第二个数

    返回:
        两个数的和
    """
    return a + b

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

函数的优点

# ❌ 不推荐:重复代码
print("=== 用户1信息 ===")
print("姓名: 张三")
print("年龄: 25")
print("城市: 北京")

print("=== 用户2信息 ===")
print("姓名: 李四")
print("年龄: 30")
print("城市: 上海")

# ✅ 推荐:使用函数
def show_user_info(name, age, city):
    print(f"=== {name}信息 ===")
    print(f"姓名: {name}")
    print(f"年龄: {age}")
    print(f"城市: {city}")

show_user_info("张三", 25, "北京")
show_user_info("李四", 30, "上海")

参数详解

位置参数

def introduce(name, age, city):
    print(f"我叫{name},今年{age}岁,来自{city}")

# 必须按顺序传递
introduce("张三", 25, "北京")
# introduce(25, "张三", "北京")  # 逻辑错误

默认参数

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

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

# 注意:默认参数必须是不可变对象
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item("苹果"))      # ['苹果']
print(add_item("香蕉"))      # ['香蕉'](不会累积)

关键字参数

def create_profile(name, age, city, job):
    print(f"姓名: {name}")
    print(f"年龄: {age}")
    print(f"城市: {city}")
    print(f"职业: {job}")

# 使用关键字参数,可以不按顺序
create_profile(name="张三", age=25, city="北京", job="工程师")
create_profile(job="设计师", name="李四", age=28, city="上海")

# 混合使用
create_profile("王五", 30, job="教师", city="广州")

可变位置参数 *args

def sum_all(*args):
    """接受任意数量的位置参数"""
    total = 0
    for num in args:
        total += num
    return total

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

# args 是一个元组
def show_args(*args):
    print(f"类型: {type(args)}")
    print(f"内容: {args}")

show_args(1, 2, 3)
# 类型: <class 'tuple'>
# 内容: (1, 2, 3)

可变关键字参数 **kwargs

def create_user(**kwargs):
    """接受任意数量的关键字参数"""
    user = {}
    for key, value in kwargs.items():
        user[key] = value
    return user

user = create_user(name="张三", age=25, city="北京")
print(user)  # {'name': '张三', 'age': 25, 'city': '北京'}

# kwargs 是一个字典
def show_kwargs(**kwargs):
    print(f"类型: {type(kwargs)}")
    print(f"内容: {kwargs}")

show_kwargs(name="李四", age=30)
# 类型: <class 'dict'>
# 内容: {'name': '李四', 'age': 30}

组合使用所有参数类型

def complex_function(positional, default="默认值", *args, keyword_only, **kwargs):
    """
    演示所有参数类型的组合

    参数顺序必须是:
    1. 位置参数
    2. 默认参数
    3. *args
    4. 关键字-only 参数
    5. **kwargs
    """
    print(f"位置参数: {positional}")
    print(f"默认参数: {default}")
    print(f"可变位置参数: {args}")
    print(f"关键字-only参数: {keyword_only}")
    print(f"可变关键字参数: {kwargs}")

complex_function("必传", "自定义", 1, 2, 3, keyword_only="必须", extra1="额外1", extra2="额外2")

参数解包

# 列表/元组解包
def add(a, b, c):
    return a + b + c

numbers = [1, 2, 3]
result = add(*numbers)  # 等价于 add(1, 2, 3)
print(result)  # 6

# 字典解包
def greet(name, age):
    print(f"{name}, {age}岁")

info = {"name": "张三", "age": 25}
greet(**info)  # 等价于 greet(name="张三", age=25)

返回值

基本返回

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

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

返回多个值

def get_user_info():
    name = "张三"
    age = 25
    city = "北京"
    return name, age, city  # 返回元组

# 解包接收
name, age, city = get_user_info()
print(f"{name}, {age}岁, 来自{city}")

# 或者作为元组接收
info = get_user_info()
print(info)  # ('张三', 25, '北京')

返回不同类型

def divide(a, b):
    if b == 0:
        return None, "除数不能为零"
    return a / b, "成功"

result, message = divide(10, 2)
print(f"结果: {result}, 状态: {message}")

result, message = divide(10, 0)
print(f"结果: {result}, 状态: {message}")

没有返回值

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

result = greet("张三")
print(result)  # None(没有return语句,默认返回None)

early return(提前返回)

def check_age(age):
    if age < 0:
        return "无效年龄"
    if age < 18:
        return "未成年人"
    if age < 60:
        return "成年人"
    return "老年人"

print(check_age(-1))   # 无效年龄
print(check_age(15))   # 未成年人
print(check_age(25))   # 成年人
print(check_age(65))   # 老年人

变量作用域

局部变量和全局变量

global_var = "全局变量"

def test_scope():
    local_var = "局部变量"
    print(global_var)  # 可以访问全局变量
    print(local_var)   # 可以访问局部变量

test_scope()
# print(local_var)  # NameError: 无法在函数外访问局部变量

global 关键字

count = 0

def increment():
    global count  # 声明使用全局变量
    count += 1

increment()
print(count)  # 1
increment()
print(count)  # 2

nonlocal 关键字

def outer():
    x = 10

    def inner():
        nonlocal x  # 声明使用外层函数的变量
        x += 5
        print(f"inner: {x}")

    inner()
    print(f"outer: {x}")

outer()
# inner: 15
# outer: 15

LEGB 规则

Python 查找变量的顺序:

  • Local - 局部作用域
  • Enclosing - 嵌套函数作用域
  • Global - 全局作用域
  • Built-in - 内置作用域
x = "global"

def outer():
    x = "enclosing"

    def inner():
        x = "local"
        print(x)  # local

    inner()
    print(x)  # enclosing

outer()
print(x)  # global

高阶函数

函数作为参数

def apply_operation(func, a, b):
    """接受一个函数作为参数"""
    return func(a, b)

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

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

print(apply_operation(add, 3, 5))       # 8
print(apply_operation(multiply, 3, 5))  # 15

函数作为返回值

def create_multiplier(factor):
    """返回一个函数"""
    def multiplier(number):
        return number * factor
    return multiplier

double = create_multiplier(2)
triple = create_multiplier(3)

print(double(5))  # 10
print(triple(5))  # 15

map() 函数

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

# 使用 map
squares = list(map(lambda x: x**2, numbers))
print(squares)  # [1, 4, 9, 16, 25]

# 等价于列表推导式
squares = [x**2 for x in numbers]

filter() 函数

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

# 使用 filter
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4, 6, 8, 10]

# 等价于列表推导式
evens = [x for x in numbers if x % 2 == 0]

reduce() 函数

from functools import reduce

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

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

# 累乘
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 120

# 找最大值
max_value = reduce(lambda x, y: x if x > y else y, numbers)
print(max_value)  # 5

匿名函数 lambda

基本语法

# 传统函数
def add(a, b):
    return a + b

# lambda 函数
add = lambda a, b: a + b

print(add(3, 5))  # 8

常见用法

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

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

# 多条件排序
sorted_students = sorted(students, key=lambda s: (-s["score"], s["name"]))

结合高阶函数

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

# map + lambda
squares = list(map(lambda x: x**2, numbers))
print(squares)  # [1, 4, 9, 16, 25]

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

# sorted + lambda
words = ["banana", "apple", "cherry", "date"]
sorted_words = sorted(words, key=lambda w: len(w))
print(sorted_words)  # ['date', 'apple', 'banana', 'cherry']

lambda 的限制

# ✅ lambda 只能是表达式,不能有语句
add = lambda a, b: a + b

# ❌ 不能有赋值语句
# func = lambda x: y = x + 1  # SyntaxError

# ❌ 不能有循环
# func = lambda x: for i in range(x): print(i)  # SyntaxError

# ❌ 不能有异常处理
# func = lambda x: try: int(x) except: 0  # SyntaxError

装饰器

装饰器基础

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

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

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

带参数的装饰器

def timer_decorator(func):
    import time

    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():
    import time
    time.sleep(1)
    return "完成"

result = slow_function()
print(result)

保留函数元信息

from functools import wraps

def my_decorator(func):
    @wraps(func)  # 保留原函数的元信息
    def wrapper(*args, **kwargs):
        """wrapper 的文档"""
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def greet(name):
    """greet 函数的文档"""
    print(f"Hello, {name}!")

print(greet.__name__)  # greet(而不是 wrapper)
print(greet.__doc__)   # greet 函数的文档

实用装饰器示例

from functools import wraps

# 日志装饰器
def logger(func):
    @wraps(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

# 缓存装饰器
def cache(func):
    cache_dict = {}

    @wraps(func)
    def wrapper(*args):
        if args not in cache_dict:
            cache_dict[args] = func(*args)
        return cache_dict[args]

    wrapper.cache = cache_dict
    return wrapper

# 权限检查装饰器
def require_login(func):
    @wraps(func)
    def wrapper(user, *args, **kwargs):
        if not user.get("logged_in"):
            raise PermissionError("需要登录")
        return func(user, *args, **kwargs)
    return wrapper

# 使用装饰器
@logger
@cache
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))  # 55

带参数的装饰器

def repeat(times):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

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

greet("张三")
# 输出三次: Hello, 张三!

生成器

生成器函数

def count_up_to(n):
    """生成器函数:使用 yield"""
    i = 1
    while i <= n:
        yield i
        i += 1

# 创建生成器对象
counter = count_up_to(5)

# 逐个获取值
print(next(counter))  # 1
print(next(counter))  # 2
print(next(counter))  # 3

# 遍历剩余的值
for num in counter:
    print(num)  # 4, 5

生成器表达式

# 列表推导式 - 立即创建完整列表
squares_list = [x**2 for x in range(1000000)]

# 生成器表达式 - 惰性求值,节省内存
squares_gen = (x**2 for x in range(1000000))

print(type(squares_list))  # <class 'list'>
print(type(squares_gen))   # <class 'generator'>

# 逐个获取
print(next(squares_gen))  # 0
print(next(squares_gen))  # 1

生成器的优势

import sys

# 列表 - 占用大量内存
numbers_list = [x for x in range(1000000)]
print(f"列表大小: {sys.getsizeof(numbers_list)} bytes")

# 生成器 - 占用很少内存
numbers_gen = (x for x in range(1000000))
print(f"生成器大小: {sys.getsizeof(numbers_gen)} bytes")

# 处理大文件
def read_large_file(filename):
    with open(filename, 'r') as f:
        for line in f:
            yield line.strip()

# 逐行处理,不需要一次性加载整个文件
for line in read_large_file("large_file.txt"):
    process(line)

send() 和 close()

def coroutine():
    print("协程启动")
    while True:
        value = yield
        print(f"收到: {value}")

coro = coroutine()
next(coro)          # 启动协程
coro.send("Hello")  # 收到: Hello
coro.send("World")  # 收到: World
coro.close()        # 关闭协程

递归函数

基本概念

def factorial(n):
    """计算阶乘"""
    if n == 0 or n == 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))  # 120
# 5! = 5 × 4 × 3 × 2 × 1 = 120

递归三要素

  1. 基准情况(停止条件)
  2. 递归情况(调用自身)
  3. 向基准情况靠近
def fibonacci(n):
    """斐波那契数列"""
    # 基准情况
    if n <= 0:
        return 0
    if n == 1:
        return 1

    # 递归情况
    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

递归优化

# ❌ 效率低:大量重复计算
def fibonacci_slow(n):
    if n <= 1:
        return n
    return fibonacci_slow(n-1) + fibonacci_slow(n-2)

# ✅ 使用缓存优化
from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci_fast(n):
    if n <= 1:
        return n
    return fibonacci_fast(n-1) + fibonacci_fast(n-2)

# ✅ 或使用迭代
def fibonacci_iterative(n):
    if n <= 1:
        return n

    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b

递归示例

# 二分查找
def binary_search(arr, target, low=0, high=None):
    if high is None:
        high = len(arr) - 1

    if low > high:
        return -1

    mid = (low + high) // 2

    if arr[mid] == target:
        return mid
    elif arr[mid] > target:
        return binary_search(arr, target, low, mid - 1)
    else:
        return binary_search(arr, target, mid + 1, high)

numbers = [1, 3, 5, 7, 9, 11, 13, 15]
print(binary_search(numbers, 7))   # 3
print(binary_search(numbers, 6))   # -1

# 快速排序
def quick_sort(arr):
    if len(arr) <= 1:
        return arr

    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]

    return quick_sort(left) + middle + quick_sort(right)

print(quick_sort([3, 6, 8, 10, 1, 2, 1]))
# [1, 1, 2, 3, 6, 8, 10]

递归深度限制

import sys

# 查看递归深度限制
print(sys.getrecursionlimit())  # 通常是 1000

# 修改递归深度限制(谨慎使用)
sys.setrecursionlimit(2000)

# ❌ 递归过深会导致栈溢出
# def infinite_recursion(n):
#     return infinite_recursion(n + 1)
# infinite_recursion(0)  # RecursionError

综合实战

实战1: 函数式数据处理管道

from functools import reduce

class DataPipeline:
    """函数式数据处理管道"""

    def __init__(self, data):
        self.data = list(data)

    def filter(self, func):
        """过滤数据"""
        self.data = list(filter(func, self.data))
        return self

    def map(self, func):
        """转换数据"""
        self.data = list(map(func, self.data))
        return self

    def sort(self, key=None, reverse=False):
        """排序数据"""
        self.data = sorted(self.data, key=key, reverse=reverse)
        return self

    def reduce(self, func, initial=None):
        """归约数据"""
        if initial is None:
            return reduce(func, self.data)
        return reduce(func, self.data, initial)

    def take(self, n):
        """取前n个"""
        self.data = self.data[:n]
        return self

    def skip(self, n):
        """跳过前n个"""
        self.data = self.data[n:]
        return self

    def result(self):
        """获取结果"""
        return self.data

# 使用示例
numbers = range(1, 101)

result = (DataPipeline(numbers)
          .filter(lambda x: x % 2 == 0)        # 只要偶数
          .map(lambda x: x ** 2)                # 平方
          .filter(lambda x: x > 100)            # 大于100
          .sort(reverse=True)                   # 降序
          .take(10)                             # 前10个
          .result())

print("前10个大于100的偶数平方(降序):")
print(result)

# 计算总和
total = (DataPipeline(range(1, 101))
         .filter(lambda x: x % 3 == 0 or x % 5 == 0)
         .reduce(lambda x, y: x + y))

print(f"\n1-100中3或5的倍数之和: {total}")

实战2: 缓存系统

import time
from functools import wraps

class CacheSystem:
    """简易缓存系统"""

    def __init__(self, max_size=100, ttl=300):
        self.cache = {}
        self.max_size = max_size
        self.ttl = ttl  # 生存时间(秒)

    def cached(self, func):
        """缓存装饰器"""
        @wraps(func)
        def wrapper(*args, **kwargs):
            # 创建缓存键
            key = (func.__name__, args, tuple(sorted(kwargs.items())))

            # 检查缓存
            if key in self.cache:
                result, timestamp = self.cache[key]
                if time.time() - timestamp < self.ttl:
                    print(f"缓存命中: {func.__name__}")
                    return result
                else:
                    del self.cache[key]

            # 执行函数
            print(f"执行函数: {func.__name__}")
            result = func(*args, **kwargs)

            # 存储缓存
            if len(self.cache) >= self.max_size:
                # 删除最旧的缓存
                oldest_key = min(self.cache, key=lambda k: self.cache[k][1])
                del self.cache[oldest_key]

            self.cache[key] = (result, time.time())
            return result

        wrapper.clear_cache = lambda: self.cache.clear()
        wrapper.cache_info = lambda: len(self.cache)
        return wrapper

# 使用示例
cache = CacheSystem(max_size=50, ttl=60)

@cache.cached
def expensive_computation(n):
    """模拟耗时计算"""
    time.sleep(2)
    return sum(i ** 2 for i in range(n))

# 第一次调用(慢)
start = time.time()
result1 = expensive_computation(1000)
print(f"结果: {result1}, 耗时: {time.time() - start:.2f}秒")

# 第二次调用(快,从缓存)
start = time.time()
result2 = expensive_computation(1000)
print(f"结果: {result2}, 耗时: {time.time() - start:.2f}秒")

print(f"缓存大小: {expensive_computation.cache_info()}")

实战3: 插件系统

class PluginSystem:
    """插件系统"""

    def __init__(self):
        self.plugins = {}

    def register(self, name=None):
        """注册插件装饰器"""
        def decorator(func):
            plugin_name = name or func.__name__
            self.plugins[plugin_name] = func
            print(f"插件 '{plugin_name}' 已注册")
            return func
        return decorator

    def execute(self, name, *args, **kwargs):
        """执行插件"""
        if name not in self.plugins:
            raise ValueError(f"插件 '{name}' 未找到")

        plugin = self.plugins[name]
        print(f"执行插件: {name}")
        return plugin(*args, **kwargs)

    def list_plugins(self):
        """列出所有插件"""
        return list(self.plugins.keys())

# 创建插件系统
plugins = PluginSystem()

# 注册插件
@plugins.register()
def greet(name):
    return f"你好, {name}!"

@plugins.register()
def add(a, b):
    return a + b

@plugins.register(name="multiply")
def mul(a, b):
    return a * b

@plugins.register()
def uppercase(text):
    return text.upper()

# 使用插件
print(plugins.execute("greet", "张三"))
print(plugins.execute("add", 10, 20))
print(plugins.execute("multiply", 5, 6))
print(plugins.execute("uppercase", "hello world"))

print(f"\n已注册插件: {plugins.list_plugins()}")

实战4: 验证器系统

from functools import wraps

class Validator:
    """参数验证器"""

    @staticmethod
    def type_check(**type_specs):
        """类型检查装饰器"""
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                # 检查位置参数
                for i, (param_name, expected_type) in enumerate(type_specs.items()):
                    if i < len(args):
                        if not isinstance(args[i], expected_type):
                            raise TypeError(
                                f"参数 '{param_name}' 期望类型 {expected_type.__name__}, "
                                f"实际类型 {type(args[i]).__name__}"
                            )

                # 检查关键字参数
                for param_name, value in kwargs.items():
                    if param_name in type_specs:
                        expected_type = type_specs[param_name]
                        if not isinstance(value, expected_type):
                            raise TypeError(
                                f"参数 '{param_name}' 期望类型 {expected_type.__name__}, "
                                f"实际类型 {type(value).__name__}"
                            )

                return func(*args, **kwargs)
            return wrapper
        return decorator

    @staticmethod
    def range_check(param_name, min_val=None, max_val=None):
        """范围检查装饰器"""
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                # 获取参数值
                sig = func.__code__.co_varnames
                if param_name in sig:
                    idx = sig.index(param_name)
                    if idx < len(args):
                        value = args[idx]
                    elif param_name in kwargs:
                        value = kwargs[param_name]
                    else:
                        return func(*args, **kwargs)

                    # 检查范围
                    if min_val is not None and value < min_val:
                        raise ValueError(f"'{param_name}' 不能小于 {min_val}")
                    if max_val is not None and value > max_val:
                        raise ValueError(f"'{param_name}' 不能大于 {max_val}")

                return func(*args, **kwargs)
            return wrapper
        return decorator

    @staticmethod
    def not_empty(param_name):
        """非空检查装饰器"""
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                sig = func.__code__.co_varnames
                if param_name in sig:
                    idx = sig.index(param_name)
                    if idx < len(args):
                        value = args[idx]
                    elif param_name in kwargs:
                        value = kwargs[param_name]
                    else:
                        return func(*args, **kwargs)

                    if not value:
                        raise ValueError(f"'{param_name}' 不能为空")

                return func(*args, **kwargs)
            return wrapper
        return decorator

# 使用验证器
validator = Validator()

@validator.type_check(name=str, age=int, score=float)
@validator.range_check("age", min_val=0, max_val=150)
@validator.range_check("score", min_val=0, max_val=100)
@validator.not_empty("name")
def create_student(name, age, score):
    """创建学生记录"""
    return {
        "name": name,
        "age": age,
        "score": score
    }

# 正常调用
student = create_student("张三", 20, 85.5)
print(f"学生创建成功: {student}")

# 错误调用
try:
    create_student("", 20, 85.5)  # 名字为空
except ValueError as e:
    print(f"错误: {e}")

try:
    create_student("李四", 200, 85.5)  # 年龄超出范围
except ValueError as e:
    print(f"错误: {e}")

try:
    create_student("王五", "二十", 85.5)  # 类型错误
except TypeError as e:
    print(f"错误: {e}")

实战5: 事件系统

from collections import defaultdict

class EventEmitter:
    """事件发射器"""

    def __init__(self):
        self.listeners = defaultdict(list)

    def on(self, event_name):
        """注册事件监听器"""
        def decorator(func):
            self.listeners[event_name].append(func)
            return func
        return decorator

    def emit(self, event_name, *args, **kwargs):
        """触发事件"""
        if event_name not in self.listeners:
            return

        results = []
        for listener in self.listeners[event_name]:
            try:
                result = listener(*args, **kwargs)
                results.append(result)
            except Exception as e:
                print(f"监听器错误: {e}")

        return results

    def off(self, event_name, func=None):
        """移除监听器"""
        if func:
            self.listeners[event_name].remove(func)
        else:
            self.listeners[event_name].clear()

# 使用示例
events = EventEmitter()

@events.on("user_login")
def log_login(username):
    print(f"[日志] 用户 {username} 登录")

@events.on("user_login")
def send_welcome_email(username):
    print(f"[邮件] 发送欢迎邮件给 {username}")

@events.on("user_logout")
def log_logout(username):
    print(f"[日志] 用户 {username} 登出")

@events.on("order_created")
def process_order(order_id, amount):
    print(f"[订单] 处理订单 {order_id}, 金额: ¥{amount}")
    return "订单处理完成"

# 触发事件
print("=== 用户登录 ===")
events.emit("user_login", "张三")

print("\n=== 创建订单 ===")
results = events.emit("order_created", "ORD001", 299.99)
print(f"结果: {results}")

print("\n=== 用户登出 ===")
events.emit("user_logout", "张三")

常见错误与注意事项

1. 可变默认参数陷阱

# ❌ 危险:可变对象作为默认参数
def append_to(element, lst=[]):
    lst.append(element)
    return lst

print(append_to(1))  # [1]
print(append_to(2))  # [1, 2](不是预期的 [2])

# ✅ 正确:使用 None 作为默认值
def append_to_safe(element, lst=None):
    if lst is None:
        lst = []
    lst.append(element)
    return lst

print(append_to_safe(1))  # [1]
print(append_to_safe(2))  # [2]

2. 闭包中的变量捕获

# ❌ 陷阱:延迟绑定
functions = []
for i in range(5):
    functions.append(lambda: i)

print([f() for f in functions])  # [4, 4, 4, 4, 4](都是4)

# ✅ 正确:使用默认参数捕获当前值
functions = []
for i in range(5):
    functions.append(lambda x=i: x)

print([f() for f in functions])  # [0, 1, 2, 3, 4]

3. 递归深度限制

import sys

# ❌ 可能导致栈溢出
def deep_recursion(n):
    if n == 0:
        return 0
    return deep_recursion(n - 1)

# deep_recursion(2000)  # RecursionError

# ✅ 使用迭代替代
def iterative_solution(n):
    result = 0
    for i in range(n):
        result += i
    return result

4. 忘记返回值

# ❌ 忘记 return
def add(a, b):
    result = a + b
    # 忘记 return result

print(add(1, 2))  # None

# ✅ 确保有返回值
def add(a, b):
    return a + b

5. 全局变量滥用

# ❌ 不推荐:依赖全局变量
count = 0

def increment():
    global count
    count += 1

# ✅ 推荐:使用类或返回值
class Counter:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1
        return self.count

小结

概念说明使用场景
基础函数def 定义,return 返回代码复用
参数类型位置、默认、*args、**kwargs灵活接口设计
作用域Local, Enclosing, Global, Built-in变量管理
高阶函数函数作为参数或返回值函数式编程
Lambda匿名函数简单回调、排序
装饰器增强函数功能日志、缓存、权限
生成器yield 惰性求值大数据处理
递归函数调用自身分治算法

核心要点

  • 函数是代码复用的基本单位
  • 合理使用参数类型提高灵活性
  • 理解作用域避免变量冲突
  • 装饰器是强大的代码增强工具
  • 生成器适合处理大数据流
  • 递归要确保有终止条件
  • 避免可变默认参数陷阱

掌握函数是成为 Python 高手的关键!