0
点赞
收藏
分享

微信扫一扫

Python中装饰器的写法大全

夜空一星 2022-04-02 阅读 44
python

装饰器

装饰器来自 Decorator 的直译。什么叫装饰,就是装点、提供一些额外的功能。在 python 中的装饰器则是提供了一些额外的功能。

装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

装饰器用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

一.一个装饰器的写法

def mylog(func):
    def innfunc(*args,**kwargs):
        print('日志记录...,start')
        func(*args,**kwargs)
        print('日志记录...,end')
    return innfunc
@mylog
def func1():
    print('功能1')
@mylog
def func2(a,b,c):
    print('功能2',a,b,c)

func1()
func2(100,200,300)

二.多个装饰器的写法

#多个装饰器
#在函数定义阶段:执行顺序是从最靠近函数的装饰器开始,自内而外的执行
#在函数执行阶段:执行顺序由外而内,一层层执行
import time

def mylog(func):
    print('mylog,start!')
    def innfunc():
        print('日志记录,start')
        func()
        print('日志记录,end')
    print('mylog,end!')
    return innfunc

def cost_time(func):
    print('cost_time,start!')
    def innfunc():
        print('开始计时')
        start = time.time()
        func()
        end = time.time()
        print(f'总共耗时:{end-start}')
    print('cost_time,end!')
    return innfunc

@mylog
@cost_time  #先执行cost_time→mylog的外在函数,然后先执行mylog→cost_time的内部函数
def func2():
    print('func2')
    time.sleep(3)

func2()

三.带参数的装饰器典型写法

#带参数的装饰器的典型写法

def mylog(type):
    def decorator(func):
        def innfunc(*args,**kwargs):
            if type == '文件':
                print('文件中:日志记录....')
            else:
                print('控制台:日志记录....')
            return func(*args,**kwargs)
        return innfunc
    return decorator

@mylog('文件')
def func2(a,b):
    print('func2',a,b)

if __name__ == '__main__':
    func2(100,200)

四.类装饰器的写法

#类装饰器

class MylogDecorator():
    def __init__(self,func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print('日志记录...')
        return self.func(*args, **kwargs)

@MylogDecorator
def func2():
    print('func2')

if __name__ == '__main__':
    func2()

综合练习

缓存和计时装饰器的综合练习

# 缓存和计时装饰器的综合练习
import time

class CacheDecorator():
    __cache={}
    def __init__(self,func):
        self.func = func
    def __call__(self, *args, **kwargs):
        # 如果缓存中有对应的方法名,则直接返回对应的返回值
        if self.func.__name__ in CacheDecorator.__cache:
            return CacheDecorator.__cache[self.func.__name__]
        # 如果缓存中没有对应的方法名,则进行计算,并将结果缓存
        else:
            result = self.func(*args,**kwargs)
            CacheDecorator.__cache[self.func.__name__] = result
            return result

def cost_time(func):
    def infunc(*args,**kwargs):
        start = time.time()
        result = func(*args,**kwargs)
        end = time.time()
        print(f"耗时:{end-start}")
        return result
    return infunc

@cost_time
@CacheDecorator
def func1_long_time():
    """模拟耗时较长,每次执行返回结果都一样的情况"""
    print("start func1")
    time.sleep(3)
    print("end func1")
    return 999
if __name__ == '__main__':
    r1 = func1_long_time()
    r2 = func1_long_time()
    print(r1)
    print(r2)
举报

相关推荐

0 条评论