不了解闭包的同学可以看我之前的文章闭包是啥?
核心观点:装饰器 = 闭包 + 额外操作
作用:再不改变原函数的基础上,给函数加功能
举个栗子
1. 生活中的装饰器例子
场景:给手机加一个防摔手机壳
代码展示
def 防摔壳(手机):
def 增强版手机():
手机() # 原功能不变
print("防摔能力+1") # 新增功能
return 增强版手机
@防摔壳
def 我的手机():
print("打电话")
print("拍照")
我的手机()
# 输出:
# 打电话
# 拍照
# 防摔能力+1
现在请从来没有学过的同学把中文改成代码!!!
现在请从来没有学过的同学把中文改成代码!!!
现在请从来没有学过的同学把中文改成代码!!!
ok,现在你应该学到了0.5发部分了
这是一个闭包:
# 闭包的核心代码(剥离装饰器语法糖)
def outer(fun): # 外部函数接收参数
def inner(): # 内部函数(闭包)
# 使用外部函数的变量fun,即使outer()执行完毕,inner仍能访问fun
fun() # 闭包捕获了fun变量
return inner # 返回闭包函数
# 闭包的形成过程
original_func = my_count # 原函数
closure = outer(original_func) # 闭包 = inner函数 + 捕获的fun变量
closure() # 实际执行的是inner()
而这是一个装饰器
import time
# 1. 定义装饰器:outer是一个装饰器工厂函数
def outer(fun): # fun是被装饰的原始函数(例如my_count)
# 2. 闭包结构:inner函数捕获了外部作用域的fun变量
def inner():
# 3. 在调用原始函数前后添加计时逻辑
start = time.time() # 记录开始时间
fun() # 执行被装饰的原始函数
end = time.time() # 记录结束时间
# 4. 打印函数执行时间(闭包保留了fun的上下文,所以能获取函数名)
print(f'{fun.__name__}执行时间是{end-start}')
# 5. 返回闭包函数(关键!闭包在此形成)
return inner
# 6. 使用装饰器:等价于 my_count = outer(my_count)
@outer
def my_count():
s = 0
for i in range(1000001): # 累加0到100万的数字
s += i
print(s) # 输出结果:500000500000
# 7. 调用被装饰后的函数
my_count()