装饰器
装饰器
装饰器的底层、原理
代码示例:
# 闭包
def w1(func):
def inner():
print("权限认证中···")
func() # ---> 即调用了f1()
return inner
@w1
def f1():
print("f1")
@w1
def f2():
print("f2")
f1()
f2()
"""
输出结果:
权限认证中···
f1
权限认证中···
f2
"""
应用场景
"""
需求:初创公司又N个业务部门,1个基础平台部门,基础平台负责提供底层的功能,如:数据库操作、redis调用、监控API等功能。
业务部门使用基础功能时,只需调用基础平台提供的功能即可,如下:
# 基础平台提供的功能如下:
def f1()
print("f1")
def f2()
print("f2")
def f3()
print("f3")
def f4()
print("f4")
# 业务部门A:调用基础平台提供的功能
f1()
f2()
f3()
f4()
# 业务部门B:调用基础平台提供的功能
f1()
f2()
f3()
f4()
目前公司有条不絮的进行着,但是,以前基础平台的开发人员在写代码的时候,没有关注验证相关的问题,
即:基础平台提供的功能可以被任何人使用。
现在需要对基础平台的所有功能进行重构,为平台提供的所有功能添加验证机制,
即:执行功能前,先进行验证。
"""
# 闭包
def w1(func):
def inner():
# 验证1
# 验证2
# 验证3
func()
return inner
# 装饰器
@w1
def f1():
print("f1")
@w1
def f2():
print("f2")
@w1
def f3():
print("f3")
@w1
def f4():
print("f4")
两个装饰器
# 定义函数:完成包裹数据
def makeBold(fn):
print("---makeBold---")
def wrapped():
print("---makeBold1---")
return "<b>" + fn() + "</b>"
return wrapped
# 定义函数:完成包裹数据
def makeItalic(fn):
print("---makeItalic---")
def wrapped():
print("---makeItalic1---")
return "<i>" + fn() + "</i>"
return wrapped
@makeBold
# a=makeBold(wrapped) ---> 得到makeBold里面的wrapped内存地址 调用了 makeItalic里面的wrapped a指向了makeBold里面的wrapped()
@makeItalic
# a=makeItalic(test1) ---> 得到makeItalic里面的wrapped内存地址 调用了 test1 a指向了makeItalic里面的wrapped()
def test1():
return "hello world"
a = test1()
print(a)
"""
输出结果:
---makeItalic---
---makeBold---
---makeBold1---
---makeItalic1---
<b><i>hello world</i></b>
"""
对有参数的函数进行装饰
def funct(funName):
print("开始装饰")
def funct_inner(num): # 如果这个地方没有参数,则12行代码调用失败
print("开始执行Inner方法")
funName(num) # 如果这个地方没有参数,则第9行代码调用失败
return funct_inner
@funct
def test(num):
print(num)
a = test(10)
"""
输出结果:
开始装饰
开始执行Inner方法
10
"""
对不定长参数的函数进行装饰
def funct(funName):
print("开始装饰")
def funct_inner(*args): # 如果这个地方没有参数,则12行代码调用失败
print("开始执行Inner方法")
funName(*args) # 如果这个地方没有参数,则第9行代码调用失败
return funct_inner
@funct
def test(num,*args):
print(num,*args)
a = test(10,20,30,40,50)
"""
输出结果:
开始装饰
开始执行Inner方法
10 20 30 40 50
"""
对有返回值的函数进行装饰
def funct(funName):
print("开始装饰")
def funct_inner():
print("开始执行Inner方法")
tmp = funName()
return tmp
return funct_inner
@funct
def test():
return "我是世界上最美丽的人"
a = test()
print(a)
"""
输出结果:
开始装饰
开始执行Inner方法
我是世界上最美丽的人
"""
通用的装饰器
def funct(funName):
def funct_inner(*args,**kwargs):
tmp = funName(*args,**kwargs)
return tmp
return funct_inner
@funct
def test():
return "我是世界上最美丽的人"
@funct
def test1(num):
print(num)
a = test()
print("a的值是:",a)
a1 = test1(10)
print("a1的值是:",a1)
"""
输出结果:
a的值是: 我是世界上最美丽的人
10
a1的值是: None
"""
带有参数的装饰器
def outer(keyArgs):
def funct(funName):
def funct_inner(*args,**kwargs):
print("您目前访问的路径是:{}".format(keyArgs))
tmp = funName(*args,**kwargs)
return tmp
return funct_inner
return funct
@outer("/temp") # 在装饰器外面,再套一个方法
def test():
return "我是世界上最美丽的人"
@outer("/qq") # 在装饰器外面,再套一个方法
def test1():
return "我是世界上最美丽的人"
a = test()
print("a的值是:",a)
b = test1()
print("b的值是:",b)
"""
输出结果:
您目前访问的路径是:/temp
a的值是: 我是世界上最美丽的人
您目前访问的路径是:/qq
b的值是: 我是世界上最美丽的人
"""