目录
一、闭包的概念
1.概念
闭包(Closure)指一个函数捕获并保存了其外部作用域的变量,即使外部函数已经执行完毕。闭包允许函数访问其定义时的上下文环境,而不仅限于当前作用域。
2.闭包的特征
- 一个函数里嵌套另一个函数
- 内部函数引用外部函数的变量
- 外部函数返回内部函数本身,而不是调用结果
def outer_function(x):
def inner_function(y):
return x + y # 引用了外部函数的变量x
return inner_function # 返回内部函数对象
closure = outer_function(10)
print(closure(5)) # 输出15(10 + 5)
3.闭包的作用
- 保留状态:外层函数的变量不会因为函数执行完而被销毁;
- 实现工厂函数:比如创建多个带不同参数的函数;
- 实现装饰器(decorators)的基础。
二、装饰器
1.什么是装饰器
装饰器是一种在闭包的基础上,在不修改原函数代码的基础上,可以给函数扩展一些特定的功能,装饰器本质也是一个函数,是一个接受函数作为参数的高阶函数
2.装饰器的作用
1.统计代码耗时
import time
def cost_time(fun):
def clac(*args):
start = time.time()
r = fun(*args)
print(f"{fun.__name__}是{r}")
end = time.time()
print(f"耗时是{end - start}")
return r
return clac
def FB(i):
if i == 1 or i == 2:
return 1
else:
return FB(i-1) + FB(i - 2)
def xh(n):
a = 1
b = 1
for i in range(3,n + 1):
c = a + b
a = b
b = c
if i == n:
return c
dg = cost_time(xh)
FB = cost_time(FB)
FB(10)
dg(10)
2.对代码进行权限检查
from functools import wraps
user = None
def fun2(fun):
@wraps(fun)
def fun1():
global user
if user:
fun()
else:
name = input("用户名:")
psd = input("密码:")
if name == 'admin' and psd == "123456":
user = name
fun()
else:
print("账号或密码输入错误")
return fun1
@fun2
def login():
print("欢迎登录")
@fun2
def shopping():
print("欢迎来到购物车")
def index():
print("欢迎来到首页")
login()
shopping()
3.记录日志
from datetime import time,datetime,date
def log(fun):
def log1(*args,**kwargs):
print(f"{date.today()}进行了{fun.__name__}操作,变量有{args},关键字有{kwargs}")
result = fun(*args)
print(f"{date.today()}结束了{fun.__name__}操作,返回值有{result}")
return result
return log1
@log
def add(a,b,c):
c = a + b + c
return c
add(2, 3, 4, )
3.闭包和装饰器的关系
装饰器依赖闭包实现,装饰器一般用于高级应用场景,专门用于函数增强
4.注意事项:
1.多层装饰器是按照从上到下的顺序执行
2.装饰器会覆盖原来函数名称,可以用function.wraps来修复
3.闭包修改外部变量需要用nonlocal声明变量