装饰器的作业:在不更改原功能函数内部代码,并且不改变调用方法的情况下为源代码添加新的功能

 

1、普通装饰器

 

装饰器原理:将被装饰的函数当做一个参数传到装饰器中,并且让被装饰的函数名指向装饰器内部的函数,在

装饰器的内部函数中用来接收到的参数再调用被装饰器的函数。

 

def work(func): #接收 被装饰的函数
def warp(): func() #调用 return warp @work #相当于 func=work(func) def func(): print("装饰器") func()

 

 

2、装饰带参数的函数

 

def work(func):
    def warp(a,b):
        func(a,b)
    return warp

@work
def func(a,b):
    print("数据:{0}".format(a+b))


func(1,2)#输出 数据:3

 

3、通用装饰器

def work(func):
    def warp(*args,**kwargs):
        func(*args,**kwargs)
    return warp

@work
def func(a,b):
    print("数据:{0}".format(a+b))

func(1,2)#输出 数据:3
def work(func):
    def warp(*args,**kwargs):
        res=func(*args,**kwargs)
        return res #返回原功能函数的调用结果
    return warp

@work
def func(a,b):
    print(f"装饰器{a+b}")
    return 'func'

print(func(1,3))
#输出: 装饰器4    func

 

4、装饰器装饰类

 

5、装饰器传参数

 

def work(num): #接收装饰器的参数
    def work1(func):#接收 被装饰器的函数
        def warp(*args, **kwargs):#接收 被装饰器函数的参数
            print(f"装饰器的参数{num}")
            res = func(*args, **kwargs)
            return res  # 返回原功能函数的调用结果

        return warp
    return work1

@work(10) #func=work(10)(func)
def func(a,b):
    print(f"装饰器{a+b}")
    return 'func'

print(func(1,3))
#输出:装饰器的参数10 装饰器4    func

6、多个装饰器装饰同一个函数

def work2(func):
    def warp(*args, **kwargs):
        print(f"work2---start----")
        res = func(*args, **kwargs)
        print(f"work2---end----")
    return warp

def work1(func):
    def warp(*args, **kwargs):
        print(f"work1---start----")
        res = func(*args, **kwargs)
        print(f"work1---end----")
    return warp

@work2
@work1   #func=work2(work1(func))
def func(a,b):
    print(f"装饰器{a+b}")


func(1,3)
"""
work2---start----
work1---start----
装饰器4
work1---end----
work2---end----
"""

 

7、类实现装饰器

     如果要把类当做一个装饰器来用:

    1、首先在__init__方法中,把装饰器的函数赋值给一个实例属性

    2、然后在类里面实现一个__call__方法,在call方法中调用原来的函数

class Test:
    def __init__(self,func):
        self.func=func
    def __call__(self, *args, **kwargs):
        print("类装饰器")
        self.func(self, *args, **kwargs)

 

7、函数缓存装饰器

functools.wraps():一般用来消除装饰之后的副作用(让被装饰的函数保留原有的属性)
functools.lru_cache: 缓存装饰器
  maxsize参数设置缓存内存占用上限,其值应当设为2的冥,值为None时表示没有上限。
  typed参数设置表示不同参数类型的调用是否分别缓存;如果设置为True,那fibonacci(5)和fibonacci(5.0)将分别缓存

 

from functools import lru_cache
dic={"count":0}

@lru_cache(maxsize=None)
def func(n):
    dic["count"] +=1
    if n ==1 or n ==2:
        return 1
    else:
        res=func(n-1)+func(n-2)
        return res
res=func(200)
print(res)
print(dic)