装饰器的具体应用

接上一篇继续说装饰器的具体应用:
首先看例子:

impor time
def get_time(func):
    def inner():
        agin=time.time()
        func()
        agin2=time.time()
        print('运行函数一共耗时%f'%(agin2-agin))
    return inner

@get_time
def time1():
    time.sleep(2)
    print('in func 1')

if __name__ == '__main__':
    time1()

运行结果:

in func 1
运行函数一共耗时2.012976

这个函数在不改变原函数的情况下,计算出了函数运行的时间,这就是装饰器最基本的应用
那装饰器只能装饰一个函数吗? 当然不是

在看例子:

impor time
def get_time(func):
    def inner():
        agin=time.time()
        func()
        agin2=time.time()
        print('运行函数一共耗时%f'%(agin2-agin))
    return inner

@get_time
def time1():
    time.sleep(1)
    print('in func 1')

@get_time
def time2():
    time.sleep(2)
    print('in func 2')

运行结果:

in func 1
运行函数一共耗时1.004989
in func 2
运行函数一共耗时2.000298

那如果我们需要在函数中添加参数怎么办? 该如何解决

在看下面的例子:

import time

def get_time(func):
    def inner(*args,**kwargs):
        agin=time.time()
        func(*args,**kwargs)
        agin2=time.time()
        print('运行函数一共耗时%f'%(agin2-agin))
    return inner

@get_time
def time1(num1):
    time.sleep(1)
    print('in func %s'%num1)

@get_time
def time2(num2, num3):
    time.sleep(2)
    print('in func %s'%(num2 + num3))


if __name__ == '__main__':
    time1(2)
    time2(1,2)

运行结果:

in func 2
运行函数一共耗时1.010108
in func 3
运行函数一共耗时2.000327

因为每个装饰器能给所有的函数使用,为了确保传入的参数是合理的我们使用args与kwargs,这种装饰器也是通用装饰器

接下来看一个装饰器的注意点(被装饰函数有返回值):

import time

def get_time(func):
    def inner(*args,**kwargs):
        agin=time.time()
        func(*args,**kwargs)
        agin2=time.time()
        print('运行函数一共耗时%f'%(agin2-agin))
    return inner

@get_time
def time1(num1):
    time.sleep(1)
    print('in func %s'%num1)
    return 1000

if __name__ == '__main__':
    ret = time1(2)
    print('接收到的返回值是%s'%ret)

运行结果:

in func 2
运行函数一共耗时1.005030
接收到的返回值是None

此时接收到的ret是None那为什么没有接收到呢? 是因为咱们调用time1函数时其实是调用的inner函数所以并没有接收到

import time

def get_time(func):
    def inner(*args,**kwargs):
        agin=time.time()
        ret = func(*args,**kwargs)
        agin2=time.time()
        print('运行函数一共耗时%f'%(agin2-agin))
        return ret
    return inner

@get_time
def time1(num1):
    time.sleep(1)
    print('in func %s'%num1)
    return 1000

if __name__ == '__main__':
    ret = time1(2)
    print('接收到的返回值是%s'%ret)

此时的结果为:

in func 2
运行函数一共耗时1.009920
接收到的返回值是1000

咱们只需要在inner函数中接收time1返回的值并输出就可以成功接收到了

多个装饰器的使用

@外套
@长袖
def 没有穿衣服的你():
    pass

当有两个装饰器的时候,就比如你穿衣服你会先穿长袖,然后再穿外套,装饰器也是这样谁先来的就先装饰,然后在装饰外面的装饰器

举例:

def makeDiv(func):
    def inner():
        return "<div>" + func() + "<div>"
    return inner

def makeP(func):
    def inner():
        return "<p>" + func() + "<p>"
    return inner


@makeP
@makeDiv
def aaa():
    return '被装饰函数'

if __name__ == '__main__':
    print(aaa())

运行结果:

<p><div>被装饰函数<div><p>

两个装饰器装饰可以用一句代码理解:aaa=makeP(makeDiv(aaa))

那如果装饰器带有参数该如何传入函数中呢? 我们可以采用闭包把参数传入
例子:

import time
def get_num(num):
    def get_time(func):
        def inner(*args,**kwargs):
            agin=time.time()
            func(*args,**kwargs)
            agin2=time.time()
            if num == 1:
                print('运行函数一共耗时%f'%(agin2-agin))
            else:
                print('运行函数一共耗时%d'%int(agin2-agin))
        return inner
    return get_time

@get_num(1)
def time1(num1):
    time.sleep(2)

if __name__ == '__main__':
    time1(2)

装饰器带有参数的情况下,我们可以采用闭包的形式传给函数,因为内部函数可以使用外部函数的参数(上篇讲过)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值