装饰器

之前写过一篇关于装饰器的文章,但是感觉写的不太好,就想着再写一篇
装饰器本质就是函数,功能是为其他函数添加附加功能
原则:
1、不修改被修饰函数的源代码
2、不修改被修饰函数的调用方式
还是从需求开始,一个函数,需要知道这个函数的运行时间

#计算从1到100的和
def cal(l):
    sum = 0
    for i in l:
        sum+=i
    return sum
print(cal(range(101)))
#算出来这个函数执行的时间
import time
def cal(l):
    s_time = time.time()
    time.sleep(1)
    sum = 0
    for i in l:
        sum+=i
    e_time = time.time()
    print('运行的实时间是%s'%(e_time-s_time))
    return sum
print(cal(range(101)))

def test1():
    pass
def test2():
    pass

#如果很多个函数都要增加这个统计时间的功能,那么一个个加不仅麻烦而且还改变了源代码
def foo():
    print('nihao')
def test(func):

    print(func)
    start_tiem = time.time()
    time.sleep(1)
    func()
    stop_time = time.time()
    print('运行的实时间是%s' % (stop_time - start_tiem))
test(foo)

#这样没有修改源代码,但是修改了函数的调用方式,原来调用foo(),现在是test(foo)
#不修改foo源代码,不修改调用方式
import time
def foo():
    time.sleep(1)
    print('nihao')
def test(func):
    start_tiem = time.time()
    func()
    stop_time = time.time()
    print('运行的实时间是%s' % (stop_time - start_tiem))
    return func
res= test(foo)
res()
#可以赋值给foo()
foo = test(foo)
foo()
##这个函数多运行了一次,所以不行
#下面用函数嵌套,函数里面嵌套函数
def father(name):
    print('来自爸爸%s'%name)
    def son():
        name = '321'
        print('来自儿子%s'%name)
    son()
    #print(locals())#打印当前层的局部变量
father('123')

#son是一个包,外面的father是另外一个包;son里面封装了一个变量,father封装了一个函数,函数即变量,闭包的概念和作用域差不多
#装饰器= 高阶函数+函数嵌套+闭包  写一个架子,满足装饰器的要求
#这个就是装饰器的架子
import time
def time1(func):
    def warpper():
        #print(func)
        start_tiem = time.time()
        func()
        stop_time = time.time()
        print('运行的实时间是%s' % (stop_time - start_tiem))

    return warpper

def test():
    time.sleep(3)
    print('结束')
res = time1(test)#这个返回的是wrapper的内存地址
res()#这个只想的wrapper()这个函数,反馈到上面就是在只想test()这个函数

test = time1(test)#这个返回的是wrapper的内存地址
test()#这个只想的wrapper()这个函数,反馈到上面就是在只想test()这个函数

#这个好像已经好了,没有改变调用方式,没有改变源代码,并且执行结果反馈正确,但是每次调用都要定义变量赋值
#怎么解决  @time1相当于test = time1(test) 这个步骤
import time
def time1(func):
    def warpper():
        #print(func)
        start_tiem = time.time()
        func()
        stop_time = time.time()
        print('运行的实时间是%s' % (stop_time - start_tiem))

    return warpper
@time1#test = time1(test)
def test():
    time.sleep(3)
    print('结束')
    return '这是我要的返回值'
res= test()
print(res)#打印结果是None,为什么不是'这是我要的返回值'     ,因为加了@time1,
# 运行test()等于运行了warpper(),而这个函数的返回值是NOne,所以。。。
#那怎么才能返回正确的结果呢,这个结果呢,请看大屏幕
def time1(func):
    def warpper():
        #print(func)
        start_tiem = time.time()
        res = func()#这个地方只需要把func()赋值给res,然后在后面返回res就能解决
        stop_time = time.time()
        print('运行的实时间是%s' % (stop_time - start_tiem))
        return res

    return warpper
@time1#test = time1(test)
def test():
    time.sleep(3)
    print('结束')
    return '这是我要的返回值'
res= test()
print(res)

import time
#需求在test中增加参数,并且改完之后还要加很多参数怎么解决
def time1(func):
    def warpper(*args,**kwargs):
        #print(func)
        start_tiem = time.time()
        res = func(*args,**kwargs)#之所以这个地方也加*,是因为test()中传什么参数,在这个地方可以解析为什么参数,原封不动
        #因为func()这个函数就是test()这个函数,所以传的参数要和test()函数中的参数一致
        stop_time = time.time()
        print('运行的实时间是%s' % (stop_time - start_tiem))
        return res

    return warpper
@time1#test = time1(test)
def test(name,age):
    time.sleep(3)
    print('结束,名字是%s,年龄是%s'%(name,age))
    return '这是我要的返回值'
res= test()
print(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZhaoXuWen23

你的鼓励是我的动力,持续更新中

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值