装饰器,装饰器的语法糖,有参装饰器
装饰器
1、什么是装饰器
    装饰器是一个用来为被装饰者添加功能的工具
    被装饰者:函数
    装饰器:可以用函数实现装饰器这种工具
2、为何要用装饰器
    为了在不修改被装饰器对象源代码以及调用方式的前提下
    为被装饰对象添加上新功能
3、如何用装饰器
函数装饰器模板一
def outter(func):
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        return res
    return wrapper
例子
# 被装饰对象
# import time
#
# def index(x):
#     print('welcome to index page %s' % x)
#     time.sleep(3)
#
# index(111)
# 方案五:把wrapper伪装的跟被装饰对象一样
# import time
#
#
# def index(x):
#     print('welcome to index page %s' % x)
#     time.sleep(3)
#     return 7777
#
#
# def outter(func):  # func = 地址1
#     def wrapper(*args, **kwargs):
#         start = time.time()
#         res = func(*args, **kwargs)
#         stop = time.time()
#         print(stop - start)
#         return res
#     return wrapper
#
#
# index = outter(index)  #  index = outter(地址1)  # index -> 地址2
#
# res = index(111)  # res = wrapper(111)
# print(res)
# 方案六:把wrapper伪装的跟被装饰对象一样,更进一步
import time
def index(x):
    """
    这是index的帮助信息
    """
    print('welcome to index page %s' % x)
    time.sleep(3)
    return 7777
def outter(func):  # func = 地址1
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        stop = time.time()
        print(stop - start)
        return res
    wrapper.__doc__ = index.__doc__
    wrapper.__name__ = index.__name__
    return wrapper
index = outter(index)  #  index = outter(地址1)  # index -> 地址2
# help(index)
装饰器的语法糖
在调用之后的函数头加  @outter ,相当于outter(index的内存地址)
import time
from functools import wraps
def outter(func):  # func = 地址1
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        stop = time.time()
        print(stop - start)
        return res
    return wrapper
@outter  # index = outter(index的内存地址)
def index(x):
    """
    这是index的帮助信息
    """
    print('welcome to index page %s' % x)
    time.sleep(3)
    return 7777
res = index(225)
print(res)
叠加多个装饰器
import time
def deco1(func1):  # func1 = wrapper2的内存地址
    def wrapper1(*args, **kwargs):
        start = time.time()
        res1 = func1(*args, **kwargs)
        print(time.time() - start)
        return res1
    return wrapper1
def deco2(func2):  # func2 = wrapper3的内存地址
    def wrapper2(*args, **kwargs):
        inp_user = input('username>>>: ').strip()
        inp_pwd = input('password>>>: ').strip()
        if inp_user == 'egon' and inp_pwd == '123':
            print("登录成功")
            res2 = func2(*args, **kwargs)
            return res2
        else:
            print("登录失败")
    return wrapper2
@deco2               deco2(index的内存地址)-->wrapper2的内存地址
@deco1               deco1(wrapper2的内存地址) -> wrapper1的内存地址
def index():
    print('index功能')
    time.sleep(1)
index()
有参装饰器
运行 1 才会运行函数体内部
语法糖可直接 outter(engine = 'file')
def outter(engine = 'file'):
    def deco2(func2):
        def wrapper2(*args, **kwargs):
  1         if engine == 'file':
                inp_user = input('username>>>: ').strip()
                inp_pwd = input('password>>>: ').strip()
                if inp_user == 'egon' and inp_pwd == '123':
                    print("登录成功")
                    res2 = func2(*args, **kwargs)
                    return res2
                else:
                    print("登录失败")
            elif engine == "mysql":
                print("基于mysql的认证")
            elif engine == "ldap":
                print("基于ladp的认证")
        return wrapper2
    return deco2
@outter(engine='ldap')  # @deco2  # index=deco2(index)  # index=wrapper2
def index():
    print('index功能')
# index = deco2(index,engine='mysql')
index()  # wrapper()
# 结论:
# def outter(x,y):
#     def deco(func):
#         def wrapper(*args,**kwargs):
#             print(x,y)
#             res = func(*args,**kwargs)
#             return res
#         return wrapper
#     return deco
#
#
# @outter(111,22)
# def index():
#     print('index')
#
# index()
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号