python的装饰器详解

# 装饰器的引入
    # 为什么叫装饰器
        # 在原来的函数的基础上装饰(添加)新功能的工具
    # 装饰器有什么作用
        # 在原函数的基础上添加新功能,而不修改的原函数

# 举个例子
# 在index函数的基础上进行测试程序执行时间的功能
import time

# def index(x,y):
#     time.sleep(2)
#     print("this index is {} {}".format(x,y))

#解决办法一: 修改了源代码,违背了开闭原则
# 开闭原则: 对拓展开放,对修改关闭
# def index(x,y):
#     start = time.time()
#     time.sleep(2)    
#     print("this index is {} {}".format(x,y))
#     stop = time.time()
#     print(stop-start)

# 解决办法二:未修改源代码,函数的调用方式也未改变,但是形成了代码冗余
# def index(x,y):
#     time.sleep(2)
#     print("this index is {} {}".format(x,y))

# start = time.time()
# index(111,222)
# stop = time.time()
# print(stop-start)

# 解决办法三: 将方法二的冗余代码包装成函数,解决了代码冗余的功能,但是函数的调用方式改变了
# def index(x,y):
#     time.sleep(2)
#     print("this index is {} {}".format(x,y))

# def warpper():
#     start = time.time()
#     index(111,222)
#     stop = time.time()
#     print(stop-start)
# warpper()

# 解决办法三的优化一:因为办法三将index函数写死了,所以采用*args,**kw来将参数写活
# def index(x,y):
#     time.sleep(2)
#     print("this index is {} {}".format(x,y))

# def warpper(*args, **kw):
#     start = time.time()
#     index(*args,**kw)
#     stop = time.time()
#     print(stop-start)

# warpper(111,222)

# 解决办法三的优化二: 前面的问题暂时解决了
# 但是如果其他的函数也需要添加这个功能呢,我们是不是得再写一个函数呢
#  所以我们需要想办法将需要添加这个功能的函数名传进来
# 函数传参有两种方式: 1. 直接传参(写在参数列表里面) 2.闭包
# 在这里*args和**kw虽然能接受函数名这个参数,但是他只是个小弟
# 他只是将参数传递给需要使用的函数中去,所以我们只能采取闭包
# def index(x,y):
#     time.sleep(2)
#     print("this index is {} {}".format(x,y))

# def outter(func):
#     # func = index
#     def warpper(*args, **kw):
#         start = time.time()
#         func(*args,**kw)
#         stop = time.time()
#         print(stop-start)
#     return warpper
# # 偷梁换柱
# index = outter(index)
# index(111,222)

# 到这里还是有点小问题,若index函数有返回值呢,我们还需要再改进一下
# def index(x,y):
#     time.sleep(2)
#     print("this index is {} {}".format(x,y))
#     return 666

# def outter(func):
#     # func = index
#     def warpper(*args, **kw):
#         start = time.time()
#         ret = func(*args,**kw)
#         stop = time.time()
#         print(stop-start)
#         return ret
#     return warpper
# # 偷梁换柱
# index = outter(index)
# index(111,222)

# 改到这里差不多装饰器的基本功能已经实现了,但是每次都需要进行偷梁换柱
# 是不是很麻烦呢
# 所以引入了语法糖的概念,语法糖就是让你使用装饰器更加方便
# 语法糖就是在需要添加功能的函数前面加上@装饰器名
# 因为需要使用装饰器名,所以需要将装饰器函数写在函数前面

# 小提示:语法糖是从函数的上一行执行起,即自下而上的。
# 一个函数可以添加多个装饰器

def outter(func):
    # func = index
    def warpper(*args, **kw):
        start = time.time()
        ret = func(*args,**kw)
        stop = time.time()
        print(stop-start)
        return ret
    return warpper

@outter
def index(x,y):
    time.sleep(2)
    print("this index is {} {}".format(x,y))

index(111,222)

# 装饰器的内容就这多,谢谢

你可能感兴趣的:(python的装饰器详解)