装饰器

装饰器

装饰器的底层、原理

代码示例:

# 闭包
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的值是: 我是世界上最美丽的人
"""
posted @ 2022-04-18 22:06  猪腩飞了天  阅读(22)  评论(0)    收藏  举报