python学习DAY9(装饰器)

时间:2021-07-26 21:55:05
装饰器:
1.本质:是函数 (装饰其他函数)为其他函数添加附加功能
2.原则:(1)不能修改被装饰的函数的源代码(不能需要增加功能的函数的源代码)
        (2)不能修改被装饰的函数的调用方式
        

实现装饰器的相关知识:
1.函数即“变量”(即把函数体赋值给函数名)
2.高阶函数(A把一个函数名当做实参传给另外一个函数(不修改被装饰函数的源代码的情况下)、B返回值中包含函数名)
{A:实现新功能不修改源代码
import time
def test(func):
    start_time=time.time()
    func()                          #相当于运行bar()----------高阶函数的运用
    stop_time=time.time()
    print("fun time %s" %(stop_time-start_time))
def bar():
    time.sleep(3)
    print("bar")
test(bar)             #func=bar 传递的是一个内存地址  不能传bar(),因为传的只是函数体,不是内存地址
#-----------------------------------------------------------------
B:实现新功能不修改源代码且调用方式相同
import time
def bar():
    time.sleep(3)
    print("bar")
def test(func):
    print(func)
    return func          #返回一个内存地址,使调用方式能和原来相同相同
bar=test(bar)
bar()                    #做到了不修改源代码且调用方式依然相同的高阶函数(新的覆盖旧的)3.嵌套函数
def boo():
    print("in the boo")
    def too():
        print("in the too")
    too()
boo()


#-------------------------------------
高阶函数+嵌套函数=装饰器
#-------**********为test1和test2分别加上统计运行时间的功能(装饰器实现)***********------
# Author:barry allen
# -*- coding:utf-8 -*-
import time
def timer(func):
    def deco():
        start_time=time.time()
        func()
        stop_time=time.time()
        print("fun time is %s"%(stop_time-start_time))
    return deco
@timer                         #相当于test1=timer(test1)
def test1():
    time.sleep(3)
    print("in the test1")
@timer
def test2():
    time.sleep(3)
    print("in the test2")
test1()
test2()
#如test1(),先走装饰器定义,然后转到被装饰的函数,func获取该函数的地址空间,等到调用test1()的时候再走装饰器新增的功能定义(即走deco())





#*---------------------------不确定参数的装饰器
# Author:barry allen
# -*- coding:utf-8 -*-
import time
def timer(func):
    def deco(*args,**kwargs):                     #调用时没有传进参数,则为空,如果有传参数,则匹配对应的参数
        start_time=time.time()
        func(*args,**kwargs)
        stop_time=time.time()
        print("fun time is %s"%(stop_time-start_time))
    return deco
@timer
def test1(name,age):
    time.sleep(3)
    print("test1",name,age)
# @timer
# def test2():
#     time.sleep(3)
#     print("in the test2")
test1("",12)
# test2()







#---------装饰器简单应用------------
# -*-coding:utf-8 -*-
user,passwd='lin','123'
def auth(func):
    def wrapper(*args,**kwargs):
        username = input("username:").strip()
        password= input("password").strip()
        if user==username and passwd==password:
            print("\033[32;1muser has passed \33[0m")
            func(*args,**kwargs)
            '''res=func(*args,**kwargs)
               return res 
               如果源代码修改且有返回结果输出,此时在装饰器要这样写法才不会丢失有返回结果的新源代码函数
            '''
        else:
            exit("\033[31;1mfailed \33[0m")
    return wrapper

def index():
    print( "welcome to the index page")
@auth
def home():
    print("welcome to the home page")
    #return "from home"         接上个注释说明
@auth
def bbs():
    print("welcome to the bbs page")
index()
home()
#print(home())
bbs()












#-----------进阶应用
#装饰器可以定义不同的类型传进装饰器的参数,并在装饰器里面根据条件判断
__author__ = "Alex Li"
import time
user,passwd = 'alex','abc123'
def auth(auth_type):
    print("auth func:",auth_type)
    def outer_wrapper(func):
        def wrapper(*args, **kwargs):
            print("wrapper func args:", *args, **kwargs)
            if auth_type == "local":
                username = input("Username:").strip()
                password = input("Password:").strip()
                if user == username and passwd == password:
                    print("\033[32;1mUser has passed authentication\033[0m")
                    res = func(*args, **kwargs)  # from home
                    print("---after authenticaion ")
                    return res
                else:
                    exit("\033[31;1mInvalid username or password\033[0m")
            elif auth_type == "ldap":
                print("ldap......")

        return wrapper
    return outer_wrapper

def index():
    print("welcome to index page")
@auth(auth_type="local") # home = wrapper()
def home():
    print("welcome to home  page")
    return "from home"

@auth(auth_type="ldap")
def bbs():
    print("welcome to bbs  page")

index()
print(home()) #wrapper()
bbs()