装饰器(1)

一、定义

装饰器就是闭包函数的一种应用场景

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

二、作用

开放封闭原则:对修改封闭,对扩展开放

三、装饰器的使用

import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper

@timmer
def foo():
    time.sleep(3)
    print('from foo')
foo()
无参装饰器
def auth(driver='file'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name=input("user: ")
            pwd=input("pwd: ")

            if driver == 'file':
                if name == 'egon' and pwd == '123':
                    print('login successful')
                    res=func(*args,**kwargs)
                    return res
            elif driver == 'ldap':
                print('ldap')
        return wrapper
    return auth2

@auth(driver='file')
def foo(name):
    print(name)

foo('egon')

有参装饰器
有参装饰器
def auth(x,engine = "file"):
    def outter(func):
        def wrapper(*args, **kwargs):
            x
            name = input("username>: ").strip()
            pwd = input("password>: ").strip()

            if engine == "file":
                if name == "egon" and pwd == "123":
                    print('login successful'.center(50,'='))

                    res = func(*args, **kwargs)
                    return res
                else:
                    print('username or password error')
            elif engine == "mysql":
                print("基于mysql的认证")
            elif engine == "ldap":
                print("基于ldap的认证")
            else:
                print('engine不存在')
        return wrapper
    return outter

@auth(11,"file")  # @outter函数的内存地址  # index=outter函数的内存地址(index函数的内存地址)
def index():
    print('from index')
@auth(11,"mysql")
def home(name):
    print('welcome %s to home page' %name)

# index=auth(index,"file")
# home=auth(index,"ldap")

index()
home("egon")

# 模板

def outter2(x):
    def outter1(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res

        return wrapper
    return outter1


@outter2(x=1)
def index():
    pass
有参装饰器示例

 

四、装饰器语法

#被装饰函数的正上方,单独一行
        @deco1
        @deco2
        @deco3
        def foo():
            pass

        foo=deco1(deco2(deco3(foo)))

 

五、装饰器补充

from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def index():
    '''哈哈哈哈'''
    print('from index')

print(index.__doc__)

 

六、叠加多个装饰器

# 叠加多个装饰器
# 1. 加载顺序(outter函数的调用顺序):自下而上
# 2. 执行顺序(wrapper函数的执行顺序):自上而下

 

def outter1(func1): #func1=wrapper2的内存地址
    print('加载了outter1')
    def wrapper1(*args,**kwargs):
        print('执行了wrapper1')
        res1=func1(*args,**kwargs)
        return res1
    return wrapper1

def outter2(func2): #func2=wrapper3的内存地址
    print('加载了outter2')
    def wrapper2(*args,**kwargs):
        print('执行了wrapper2')
        res2=func2(*args,**kwargs)
        return res2
    return wrapper2

def outter3(func3): # func3=最原始的那个index的内存地址
    print('加载了outter3')
    def wrapper3(*args,**kwargs):
        print('执行了wrapper3')
        res3=func3(*args,**kwargs)
        return res3
    return wrapper3



@outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
@outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
@outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
def index():
    print('from index')

print('======================================================')
index()

示范代码
范例1

 

# def deco1(func1):  # func1 = wrapper2的内存地址
#     def wrapper1(*args, **kwargs):
#         print('====>wrapper1')
#         res1 = func1(*args, **kwargs)
#         return res1
#     return wrapper1
#
# def deco2(func2):  # func2 = wrapper3的内存地址
#     def wrapper2(*args, **kwargs):
#         print('====>wrapper2')
#         res2 = func2(*args, **kwargs)
#         return res2
#     return wrapper2
#
# def deco3(func3):  # func3 = index函数的内存地址
#     def wrapper3(*args, **kwargs):
#         print('====>wrapper3')
#         res3 = func3(*args, **kwargs)
#         return res3
#     return wrapper3
#
# # 加载/得到wrapper函数的顺序是自下而上的
# # 我们运行wrapper函数的顺序是:
#
#         # index=wrapper1的内存地址
# @deco1  # deco1(wrapper2的内存地址) => wrapper1的内存地址
# @deco2  # deco2(wrapper3的内存地址) => wrapper2的内存地址
# @deco3  # deco3(index函数的内存地址) => wrapper3的内存地址
# def index():
#     print('from index')
#
# # print(index)
# res=index()
# """
# ====>wrapper1
# ====>wrapper2
# ====>wrapper3
# from index
# """
import time

def timmer(func):
    def wrapper(*args,**kwargs):
        start=time.time()
        res=func(*args,**kwargs)
        stop=time.time()
        print("run time is : %s" %(stop - start))
        return res
    return wrapper  # 千万不要加括号

def auth(x,engine = "file"):
    def outter(func):
        def wrapper(*args, **kwargs):
            x
            name = input("username>: ").strip()
            pwd = input("password>: ").strip()

            if engine == "file":
                if name == "egon" and pwd == "123":
                    print('login successful'.center(50,'='))

                    res = func(*args, **kwargs)
                    return res
                else:
                    print('username or password error')
            elif engine == "mysql":
                print("基于mysql的认证")
            elif engine == "ldap":
                print("基于ldap的认证")
            else:
                print('engine不存在')
        return wrapper
    return outter

@auth(111,"file")
@timmer
def index():
    print("index=====>")
    time.sleep(3)

index()
示例2

 

 

posted @ 2020-08-08 16:02  sean_wang  阅读(84)  评论(0编辑  收藏  举报