闭包和装饰器(语法糖)
文章目录
def func1():
print("this is func1")
def func2():
print("this is func2")
return func2
var = func1()
var()
这是最基本的闭包格式:其中的执行顺序 => func1() => print(“this is func1”) => return func2 => func2() => print(“this is func2”)
其中有一个比较混淆的点(小伙伴们注意哦),其实var()是相当于func1()()这样的
好,那么接下来我们来一个真正的例子:
如果我定义一个add()两数相加的函数
def add(a, b):
print(a + b)
return a + b
add(2, 3) #5
假如我要加一个功能:这个功能是输入的两个参数都会自己先加上5再计算加法
这时候就需要用到闭包和装饰器了(装饰器就是语法糖,代码也会枯燥,他们也需要甜甜的糖)
def func1(fun):#这里的fun就是被装饰的函数
def func2(x, y)
x += 5
y += 5
return x + y
return func2
@func1 ###这里就是语法糖咯
def add(a, b):
print(a + b)
return a + b
add(2, 3)
#执行结果如下:
好的,到了这一步之后我开始谈论有参数的装饰器的问题哦!
#美剧迷的小伙伴们,都知道美国的具名电台网飞(netflix)和HBO
#我现在有一个装饰器同事装饰这两个函数,并且加入输出他们各自的著名电视剧名字
def netflix():
print("我特别有钱!")
def HBO():
print("我也特别有钱!")
def per_func(show_name):#这时候就需要在这里多加一层,传入参数方便后面判断到底是哪个电台
def func1(fun):
def func2():
if show_name == "netflix":#在这里我们就可以很好地判断
print("我有怪奇物语,杰西卡.琼斯,爱死亡与机器人...")
#Netflix的好剧哦,没看的小朋友,博主吐血推荐啦
return fun()
elif show_name == "HBO":
print("我有权利的游戏,真探...")
return fun()
else:
return "NameError"
return func2
return func1
@per_func(show_name="netflix")#加入一个对应的参数
def netflix():
print("我特别有钱!")
@per_func(show_name="HBO")
def HBO():
print("我也特别有钱!")
netflix()
HBO()
好的那么接下来我们继续讨论一个函数同时被多个装饰器装饰(幸福的娃哦,好多语法糖)
import time
import functools
def log(func):
print(f"封装了{log.__name__}")
@functools.wraps(func)
def func1(*args, **kwargs):
print(f"this is {func}")
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
return func(*args, **kwargs)
print(func.__name__)
print(func1.__name__)
return func1
def cost(func):
print(f"封装了{cost.__name__}")
@functools.wraps(func)
def func2(x, y):
print(f"this is {func}")
start = time.time()
ret = func(x, y)
cost_time = time.time() - start
print(cost_time)
return ret
print(func.__name__)
print(func2.__name__)
return func2
#执行至上而下 这里add = log(cost(add))
#封装至下而上
@log
@cost
def add(a, b):
time.sleep(1)
print(a + b)
return a + b
这就是全部啦,希望可以帮到你们