条件:
1. 外部函数中定义了内部函数
2. 外部函数是有返回值
3. 返回的值是:内部函数名
4. 内部函数引用了外部函数的变量
格式:
def 外部函数():
......
def 内部函数():
..........
return 内部函数
2.来看看闭包的几个例子
例子1
# 闭包
# 在函数中提出的概念,
def func():
a = 100
def inner_func():
b = 99
print(a, b)
return inner_func # 将函数名返回
# print(a)
# inner_func ()
x = func() # x接收函数 即inner_func()函数
# 那x只要一加括号代表是调用inner_func()
x()
-------------------------------------------------------------
# 输出
100 99
例子2
def func(a, b):
c = 1
def inner_func():
s = a + b + c
print('相加之后的结果:', s)
return inner_func
# 调用函数func
ifunc = func(3, 4) # ifung就是inner_ func ifunc=inner_ func
# 调用返出来的函数
ifunc()
-------------------------------------------------------------
# 输出
相加之后的结果: 8
3.闭包简单来说函数内嵌套函数,同时使用外部函数的变量,并将内嵌函数名返回
4.闭包有什么缺点和优点
- 缺点
- 作用域没有那么直观
- 因为变量不会被垃圾回收所以有一定的内存 占用问题。
- 作用
- 可以使用同级的作用域闭包作用
- 读取其他元素的内部变量闭包作用:
- 延长作用域
- 闭包总结
-
闭包看似优化了变量,原来需要类对象完成的工作,闭包也可以完成
-
由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存
-
闭包的好处,使代码变得简洁,便于阅读代码。
-
闭包是理解裝饰器的基础
-
1. 函数A是作为参数出现的(函数B就接收函数A作为参数)
2. 要有闭包的特点
1.举个栗子
例子1
# 定义一个装饰器
def decorate(func):
a = 100
print('wrapper打印测试.........')
# 对函数包装
def wrapper():
func()
print('装饰第一步', a)
print('装饰第二步')
print('wrapper加载完成............')
return wrapper
@decorate
def house():
print('未装修的房子')
# 调用装饰器
#此时的house并不是原来的函数了而是wrapper()这个函数了
house()
-----------------------------------------------------------
# 输出
wrapper打印测试.........
wrapper加载完成............
未装修的房子
装饰第一步 100
装饰第二步
解释:
1.house被装饰函数,
2.将被装饰函数作为参数传给装饰器decorate
3.执行decorate函数
4.将返回值又赋值给house
例子2
# 定义一个装饰器
def decorate(func):
def wrapper(*args, **kwargs):
print('校验中........')
time.sleep(3)
print('校验完毕..........')
# 调用原函数
func(*args, **kwargs)
return wrapper
@decorate
# 原函数
def f1(name, age):
print('他的名字叫{},年龄是{}'.format(name, age))
f1('zs', 21)
-----------------------------------------------------------
校验中........
校验完毕..........
他的名字叫zs,年龄是21
例子3:
多个装饰器一起使用,谁距离函数最近就优先使用哪个装饰器
# 定义装饰器
def decorate1(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print('装门..........')
return wrapper
def decorate2(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print('刷漆..........')
return wrapper
@decorate2
@decorate1
def house():
print('我是毛坯房')
house()
----------------------------------------------------------------
# 输出
我是毛坯房
装门..........
刷漆..........
例子4
带参数的装饰器
- 带参数的装饰器是三层的
- 最外层的函数负责接收装饰器的参数
- 里面的内容还是原装饰器的内容饰器
# 装饰器带参数
def outer(a): # 第一层 负责接收装饰器的参数
def decorate(func): # 第二层 负责接收函数的
def wrapper(*args, **kwargs): # 第三层 负责接函数的实参
func(*args, **kwargs)
print('---->铺地砖{}块'.format(a))#使用装饰器传入的参数
return wrapper # 返出来的是:第三层
return decorate # 返出来的是:第二层
@outer(10) # 装饰器带参数表示有三层
def house(time):
print('我在{}日期拿到房子的钥匙,是毛坯房....'.format(time))
house('2020-05-09')
------------------------------------------------------------
# 输出
我在2022-04-28日期拿到房子的钥匙,是毛坯房....
---->铺地砖10块
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)