文章目录
- 前言
- 一、闭包(Closure)
-
- [1.1 什么是闭包?](#1.1 什么是闭包?)
- [1.2 闭包的工作原理](#1.2 闭包的工作原理)
- [1.3 闭包的实际应用](#1.3 闭包的实际应用)
- 二、装饰器(Decorator)
-
- [2.1 什么是装饰器?](#2.1 什么是装饰器?)
- [2.2 装饰器的不同形式](#2.2 装饰器的不同形式)
- [2.3 类装饰器](#2.3 类装饰器)
前言
本文主要介绍闭包的概念以及特殊的闭包装饰器的基础知识。
一、闭包(Closure)
1.1 什么是闭包?
闭包是一个引用了外部作用域中变量的函数,即使外部函数已经执行完毕,内部函数仍然可以访问和修改这些变量。
python
python
print("闭包的基本概念:")
print("=" * 50)
# 闭包示例
def outer_function(msg):
"""外部函数"""
message = msg # 自由变量
def inner_function():
"""内部函数 - 闭包"""
return f"内部函数访问: {message}"
return inner_function # 返回内部函数(闭包)
# 创建闭包
closure1 = outer_function("Hello")
closure2 = outer_function("Python")
# 使用闭包
print(f"closure1(): {closure1()}")
print(f"closure2(): {closure2()}")
print(f"closure1的类型: {type(closure1)}")
print(f"closure1.__closure__: {closure1.__closure__}")
print(f"closure1.__closure__[0].cell_contents: {closure1.__closure__[0].cell_contents}")
1.2 闭包的工作原理
python
python
print("\n闭包的工作原理:")
print("=" * 50)
def counter_factory():
"""闭包工厂函数 - 创建计数器"""
count = 0 # 自由变量
def counter():
"""闭包函数"""
nonlocal count # 声明count为非局部变量
count += 1
return count
return counter
# 创建多个独立的计数器
counter_a = counter_factory()
counter_b = counter_factory()
print("计数器A:")
for i in range(3):
print(f" 第{i+1}次调用: {counter_a()}")
print("\n计数器B:")
for i in range(3):
print(f" 第{i+1}次调用: {counter_b()}")
print("\n闭包的特性验证:")
print("1. 每个闭包有自己独立的状态")
print("2. 闭包可以记住并修改外部变量")
print(f"3. counter_a is counter_b: {counter_a is counter_b}")
1.3 闭包的实际应用
python
python
print("\n闭包的实际应用:")
print("=" * 50)
# 应用1:配置管理器
def config_manager(initial_config):
"""配置管理器 - 使用闭包实现"""
config = initial_config.copy()
def get(key):
"""获取配置"""
return config.get(key)
def set(key, value):
"""设置配置"""
config[key] = value
return f"已设置 {key} = {value}"
def show_all():
"""显示所有配置"""
return config
# 返回一个包含多个方法的字典
return {
'get': get,
'set': set,
'show': show_all
}
# 使用配置管理器
manager = config_manager({'host': 'localhost', 'port': 8080})
print("初始配置:", manager['show']())
print("获取host:", manager['get']('host'))
print("设置新配置:", manager['set']('debug', True))
print("更新后配置:", manager['show']())
# 应用2:函数工厂
def power_factory(exponent):
"""创建幂函数 - 闭包作为函数工厂"""
def power(base):
return base ** exponent
return power
# 创建不同的幂函数
square = power_factory(2) # 平方函数
cube = power_factory(3) # 立方函数
sqrt = power_factory(0.5) # 平方根函数
print(f"\n平方函数: 5² = {square(5)}")
print(f"立方函数: 5³ = {cube(5)}")
print(f"平方根函数: √25 = {sqrt(25)}")
二、装饰器(Decorator)
2.1 什么是装饰器?
装饰器是一种特殊的闭包应用,用于修改或增强函数的功能,而不改变原函数的定义。
python
python
print("\n装饰器基础:")
print("=" * 50)
# 最简单的装饰器
def simple_decorator(func):
"""简单装饰器"""
def wrapper():
print("函数执行前...")
result = func()
print("函数执行后...")
return result
return wrapper
@simple_decorator
def say_hello():
"""业务函数"""
print("Hello, World!")
return "执行完成"
# 使用装饰器
result = say_hello()
print(f"返回值: {result}")
2.2 装饰器的不同形式
- 装饰带参数的函数
python
python
print("\n装饰带参数的函数:")
print("=" * 50)
def log_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
@log_decorator
def add(a, b):
"""加法函数"""
return a + b
@log_decorator
def greet(name, greeting="Hello"):
"""问候函数"""
return f"{greeting}, {name}!"
# 测试
print("测试add函数:")
print(f"结果: {add(3, 5)}")
print("\n测试greet函数:")
print(f"结果: {greet('Alice', greeting='Hi')}")
print(f"结果: {greet('Bob')}")
- 装饰器带参数
python
python
print("\n装饰器带参数:")
print("=" * 50)
def repeat(num_times):
"""重复执行装饰器"""
def decorator(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(3)
def say_hi(name):
"""简单的问候函数"""
return f"Hi, {name}!"
# 测试
print("测试重复装饰器:")
results = say_hi("Charlie")
print(f"所有结果: {results}")
- 多个装饰器
python
python
print("\n多个装饰器:")
print("=" * 50)
def bold_decorator(func):
"""加粗装饰器"""
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return f"**{result}**"
return wrapper
def italic_decorator(func):
"""斜体装饰器"""
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return f"*{result}*"
return wrapper
# 多个装饰器的应用顺序:从下往上
@bold_decorator
@italic_decorator
def get_text():
"""获取文本"""
return "装饰器测试"
# 相当于:bold_decorator(italic_decorator(get_text))
print("装饰后的文本:", get_text())
2.3 类装饰器
python
python
print("\n类装饰器:")
print("=" * 50)
# 类作为装饰器
class TimerDecorator:
"""计时装饰器类"""
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
import time
start_time = time.time()
result = self.func(*args, **kwargs)
end_time = time.time()
print(f"函数 {self.func.__name__} 执行时间: {end_time - start_time:.6f}秒")
return result
@TimerDecorator
def slow_function():
"""模拟耗时函数"""
import time
time.sleep(0.5)
return "任务完成"
print("测试计时装饰器:")
result = slow_function()
print(f"结果: {result}")
# 带参数的类装饰器
print("\n带参数的类装饰器:")
print("=" * 50)
class RetryDecorator:
"""重试装饰器类"""
def __init__(self, max_retries=3):
self.max_retries = max_retries
def __call__(self, func):
def wrapper(*args, **kwargs):
for attempt in range(self.max_retries):
try:
print(f"第{attempt + 1}次尝试...")
return func(*args, **kwargs)
except Exception as e:
if attempt == self.max_retries - 1:
raise e
print(f"失败: {e}, 准备重试...")
return wrapper
@RetryDecorator(max_retries=3)
def risky_operation():
"""有风险的函数"""
import random
if random.random() < 0.7:
raise ValueError("随机失败")
return "操作成功"
print("测试重试装饰器:")
try:
result = risky_operation()
print(f"结果: {result}")
except Exception as e:
print(f"最终失败: {e}")