Python中的装饰器详解

本文要点:

1.装饰器介绍
2.语法糖
3.装饰器的应用
4.多个装饰器的使用
1.装饰器介绍:
装饰器就是对被装饰的对象(类,函数)进行重构的,可以在不改变原来对象的情况下调用对象时执行重构的行为,在不改变原函数的基础上,给函数增加功能。
特点:把一个函数当作参数,返回一个替代版的函数,本质就是一个返回函数的函数
def func1():
    print('Hello,World')
#如果我们想要实现的功能是在此基础上在打印一句话怎么办,
#有人会说直接在函数内部在写上对应的功能就好了,可是在生
#产环境中往往是不能修改已经写好的代码的,那么怎么办呢
def outer():
    func1()  #调用前面的函数
    print('login...')
outer()
#这种方法貌似可以实现,可是功能复杂后每次都要调用还是不合理的
使用装饰器
def desc(fun):
    def add_info():
        print('国庆快乐~')
        fun()
    return add_info


@desc                               ##语法糖,用来连接装饰器和函数
def login():
    print('login...')
@desc
def logout():
    print('logout...')

login()
logout()

函数执行顺序:在执行login()的时候,由于有装饰器,所以先执行装饰器,执行print函数,fun()跳到login()函数,然后返回到装饰器发现函数执行完毕,跳到login()
此函数执行完毕
运行结果

国庆快乐~
login...
国庆快乐~
logout...
2.装饰器的应用
import time

def decorator(func):
    def wrapper():
        print(time.time())                         #打印系统时间
        func()
    return wrapper

@decorator
def f1():
    print('This is a function...')
@decorator
def f2():
    print('This is a function...')

f1()
f2()

运行结果

1554977829.1020477
This is a function...
1554977829.1020703
This is a function...
语法糖连承接之后,装饰器从上到下执行
3.装饰器中带有参数
import time


def decorator(func):
    def warpper(*args,**kwargs):                   #装饰器中可以加参数,如可变参数,关键字参数
        print(time.time())
        func(*args,**kwargs)
    return warpper


@decorator
def f1(func_name):
    print('This is a function ' + func_name)

@decorator
def f2(func_name1,func_name2):
    print('This is a function ' + func_name1)
    print('This is a function ' + func_name2)

@decorator
def f3(func_name1,func_name2,**kwargs):
    print('This is a function ' + func_name1)
    print('This is a function ' + func_name2)
    print(kwargs)

f1('test')
f2('test1','test2')
f3('test1','test2',a=1,b=2,c='westos')

运行结果:

1554978357.8987756
This is a function test
1554978357.8988152
This is a function test1
This is a function test2
1554978357.898822
This is a function test1
This is a function test2
{'a': 1, 'b': 2, 'c': 'westos'}
4.有返回值的装饰器
import time
import functools

def add_log(fun):
    @functools.wraps(fun)
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = fun(*args,**kwargs)        #函数本身有返回值,要在函数最后将数据返回,不然在调用函数的时候
        end_time = time.time()           #无法得到结果,只是在函数内部运行
        print('[%s] 函数名: %s, 运行时间: %6f,运行返回值结果: %d' %(time.ctime(),fun.__name__,end_time - start_time,res))
        return res
    return wrapper

@add_log
def add(x,y):
    time.sleep(1)
    return x + y

add(1,2)

运行结果

[Thu Apr 11 18:33:22 2019] 函数名: add, 运行时间: 1.000905,运行返回值结果: 3
5.多个装饰器
如果要添加复杂的功能的时候,一个装饰器远远不过,如何添加多个装饰器呢
def decorator_a(fun):
    print('Get in decorator_a')

def inner_a(*args, **kwargs):
    print('Get in inner_a')
    res = fun(*args, **kwargs)
    return res

return inner_a


def decorator_b(fun):
    print('Get in decorator_b')
def inner_b(*args, **kwargs):
    print('Get in inner_b')
    res = fun(*args, **kwargs)
    return res

return inner_b


@decorator_a      		#当有多个装饰器的是装饰器由下到上执行,即先执行b在在执行a
@decorator_b
def f(x):
    print('Get in f')
    return x * 2

f(2)

运行结果:

Get in decorator_b
Get in decorator_a
Get in inner_a
Get in inner_b
Get in f
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值