python闭包函数和装饰器
闭包函数
闭包的特点就是内部函数引用了外部函数中的变量
1.闭:定义在函数内部的函数
2.包:内部函数使用了外层函数名称空间中的名字
def outer():
name = 'python'
def inner():
print(name)
return inner
index = outer()
index()
'闭包中被内部函数引用的变量,不会因为外部函数结束而被释放掉,而是一直存在内存中,直到内部函数被调用结束'
闭包函数的实际应用
1. 保护变量
2. 可以让一个变量常驻内存
3. 迭代器
__iter__() 可迭代对象. 获取迭代器
__next__() + __iter__() 迭代器
特点:
1. 惰性机制
2. 只能向前
3. 节省内存
for循环的内部就是迭代器
'闭包函数是给函数体传参的另外一种方式'
def index(username):
print(username)
index('mark')
def outer():
username = 'jason'
def index():
print(username)
return index
res = outer()

装饰器简介
在不改变被装饰对象原有的'调用方式'和'内部代码'
的情况下给被装饰对象添加新的功能
对扩展开放
对修改封闭
import time
def index():
time.sleep(3)
print('from index')
'''给index函数增加了一个统计执行时间的功能'''
start_time = time.time()
index()
end_time = time.time()
print(end_time - start_time)
简易版本的装饰器
直接通过传参的方式
缺陷1:
代码写死了 无法统计其他函数的执行时间
能否解决?
可以! 将函数名通过形参的形式传入
缺陷2:
封装成函数之后 调用方式改变了 不符合装饰器原则
import time
def get_time(func):
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
def home():
time.sleep(3)
print('from home')
get_time(home)
'第一种直接给函数体传参的方式无法实现装饰器'
import time
def index():
time.sleep(1)
print('from index')
def home():
time.sleep(3)
print('from home')
print(home)
def outer(func):
def get_time():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return get_time
def outer(func_name):
def inner():
start_time = time.time()
func_name()
end_time = time.time()
print(end_time - start_time)
return inner
index = outer(index)
index()
进阶版本装饰器
def outer(index):
def inner(*args,**kwargs):
start_time = time.time()
index()
end_time =time.time()
print(end_time - start_time)
return inner
完整版本装饰器
'解决返回值的问题'
import time
def index():
time.sleep(1)
print('from index')
def outer(index):
def inner(*args,**kwargs):
start_time = time.time()
res=index(*args,**kwargs)
end_time =time.time()
print(end_time - start_time)
return
return inner
index = outer(index)
index()
装饰器模板
'''编写装饰器其实有一套固定的代码 不需要做任何理解'''
def outer(func_name):
def inner(*args, **kwargs):
print('执行被装饰函数之前 可以做的额外操作')
res = func_name(*args, **kwargs)
print('执行被装饰函数之后 可以做的额外操作')
return res
return inner
装饰器的语法糖
import time
def show_time(func):
def inner():
start_time =time.time()
func()
end_time=time.time()
print('服务器响应时间:',end_time-start_time)
return inner
@show_time
def func():
print('执行用例')
time.sleep(1)
func()
import time
def have_para(name):
def show_time(func):
def inner():
start_time =time.time()
func()
end_time=time.time()
print('服务器响应时间:',end_time-start_time)
print('执行者:',name)
return inner
return show_time
@have_para('wendy')
def func():
print('执行用例')
time.sleep(1)
func()
'''
语法糖内部原理
1.使用的时候最好紧跟在被装饰对象的上方
2.语法糖会自动将下面紧挨着的函数名传给@后面的函数调用
'''
装饰器修复技术
from functools import wraps
def outer(func_name):
@wraps(func_name)
def inner(*args, **kwargs):
print('执行被装饰对象之前可以做的操作')
res = func_name(*args, **kwargs)
return res
return inner
@outer
def index():
print('from index')
@outer
def home():
'''这是home函数的注释'''
print('from home')
help(home)
home()
index()

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人