函数的闭包
函数的嵌套调用
def func():
print(123)
def func2():
func()
print(234)
func2()
函数的嵌套定义
def func():
print(123)
def func2():
print(234)
func2() # 只能在func里面调用func2
func()
闭包
a. 闭包本质就是一种函数
b. 使用闭包一定会使用到嵌套函数
c. 闭包的意义:在变量不被别人调用的时候,最大的节省空间
d. 内部函数引用了外部函数的变量,内部函数就叫闭包
def func():
name = "chita"
def inner(): # inner就是闭包函数
print(name)
print(inner.__closure__) # 检测是不是闭包,是的话打印(<cell at 0x000001F9F5760108: str object at 0x000001F9F58564C8>,) 不是的话打印 none
ret = func()
ret()
装饰器
1. 装饰器其本质就是闭包,是特殊的闭包函数
def func():
def inner(): # inner是闭包
print('inner')
return inner
# 整个func函数就是装饰器
2. 装饰器的作用
a. 在一个函数的前后添加功能,不能修改函数的信息,并且对于用户感知不到装饰器的存在
b. 开放封闭原则, 即扩展是开放的,修改是封闭的
3. 常见装饰器
a. 被装饰函数没有参数
import time
def timmer(func):
def inner():
start = time.time()
func()
end = time.time()
print(end-start)
return inner
@timmer # 语法糖 其本质就是先执行 qqxing = timmer(qqxing),然后执行qqxing()
def qqxing(): # 被装饰的函数
for i in range(10000000):pass
print("老板万岁")
qqxing()
b. 被装饰函数有参数
import time
def timmer(func):
def inner(*args,**kwargs):
start = time.time()
ret = func(*args,**kwargs) #qqxing
end = time.time()
print(end-start)
return ret
return inner
@timmer # 语法糖 等价于qqxing = timmer(qqxing)
def qqxing(num1,num2): # 被装饰的函数
for i in range(10000000):pass
print("老板万岁")
return num1,num2
ret = qqxing(2,5)
print(ret)
最简单的装饰器
def wrapper(func):#装饰器
def inner(*args,**kwargs):
print("被装饰的函数执行之前你要做的事")
ret = func(*args,**kwargs) #func是被装饰的函数 :参数,返回值
print("被装饰的函数执行之后你要做的事")
return ret
return inner
带参数的装饰器
FLAG = False
def log(flag):
def wrapper(func):
def inner(*args,**kwargs):
if flag:
print("call :%s"%func.__name__)
ret = func(*args,**kwargs)
return ret
return inner
return wrapper
@log(FLAG) # @和log(FLAG)是分开执行的,一般都是从后往前执行
# 执行流程: wrapper =log(FLAG)
# @wrapper-->qqxing = wrapper(qqxing)--->qqxing=inner
def qqxing():
print("qqxing")
qqxing() # qqxing()=inner()
嵌套装饰器
def wrapper1(func):
def inner1():
print('wrapper1 ,before func')
func() # f
print('wrapper1 ,after func')
return inner1
def wrapper2(func):
def inner2():
print('wrapper2 ,before func')
func() # inner1
print('wrapper2 ,after func')
return inner2
@wrapper2 # f = wrapper2(wrapper1(f)) --> f = wrapper2(inner1) --> f = inner2
@wrapper1 # 谁先被调用的谁在外边,一般都是从后往前执行
def f():
print('in f')
f() # inner2()