装饰器


#装饰器,语法糖 @函数名
import time

#简单装饰器
def timer(F):
    def inner():
        start_time = time.time()
        F()
        end_time = time.time()
        print("耗时%s" % (end_time - start_time))
    return inner

@timer# 相当于 test = timer(test) 此时test变量等于 inner() 之后执行直接使用函数变量 test10 ,相当于执行inner()函数
def test10():
    for i in range(3):
        print(i)

test10()
"""
0
1
2
耗时9.059906005859375e-06
"""


#传参
def timer2(F):
    def inner(*args, **kwargs):
        start_time = time.time()
        F(*args, **kwargs)
        end_time = time.time()
        print("耗时%s" % (end_time - start_time))
    return inner#这里不能加括号

@timer2# 相当于 test11 = timer(test11) 此时test变量等于 inner() 之后执行直接使用函数变量 test11 ,相当于执行inner()函数
def test11(y):
    for i in range(y):
        print(i)

test11(3)
"""
0
1
2
耗时9.059906005859375e-06
"""

#带返回值
def timer3(F):
    def inner(*args, **kwargs):
        start_time = time.time()
        msg = F(*args, **kwargs)#保存被装饰函数返回
        end_time = time.time()
        print("耗时%s" % (end_time - start_time))
        return msg#返回被装饰函数结果
    return inner

@timer3
def test11(y):
    for i in range(y):
        print(i)
    return i

print('test11', test11(3))
"""
0
1
2
耗时7.867813110351562e-06
test11 2
"""
from functools import wraps


#装饰器函数的信息
def wrapper(Funt):
    @wraps(Funt)#保证被装饰函数拥有原来的属性
    def inner(*args, **kwargs):
        """
        装饰器
        :param args:
        :param kwargs:
        :return:
        """
        msg = Funt()
        return msg
    return inner

@wrapper
def test2():
    """
    函数说明
    :return:
    """
    pass

print(test2.__name__)#输出函数名
print(test2.__doc__)#输出函数说明


#带参数的装饰器
# flag = True
flag = False
def wrapper2(flag1):
    def wrapper1(Funt):
        @wraps(Funt)
        def inner(*args, **kwargs):
            # global flag
            if flag:
                """装饰"""
                msg = Funt('装饰')
            else:
                """不装饰"""
                msg = Funt("不装饰")
            return msg
        return inner
    return wrapper1

@wrapper2(flag)#执行顺序:1、wrapper2(flag) == wrapper1, 得到的结果是@wrapper1
def test3(a):
    print('a', a)

test3()#a 不装饰



#多个装饰器装饰一个函数
def wrapper3(F):
    def inner1():
        print("wrapper3, before")
        F()
        print("wrapper3, after")
    return inner1

def wrapper4(F):#F = inner1()
    def inner2():
        print("wrapper4, before")
        F()
        print("rapper4, after")
    return inner2

@wrapper4#2、test4 = wrapper4(test4) 实参test4是新变量test4,实际是inner1()
@wrapper3#1、执行 test4 = wrapper3(test4),test4 = inner1()
def test4():
    print("test4")

test4()
#执行结果
"""
wrapper4, before
wrapper3, before
test4
wrapper3, after
rapper4, after
"""
#练习:编写装饰器,实现注册、登陆,登陆成功一次,后续函数无需输入账号密码
status = 0

def register():
    name = input('用户名:')
    password = input('密码:')
    with open('./1.txt', mode='a+') as file:
        file.seek(0)
        while True:
            line = file.readline()
            if line:
                if name == line.split(',')[0]:
                    return "用户名已存在"
            else:
                break
        msg = name + ',' + password + '\n'
        file.write(msg)
        global status
        status = 1
        return "注册成功"

def wrapper(F):
    def inner(*args, **kwargs):
        global status
        if status == 0:
            name = input('请输入登陆用户')
            password = input('请输入密码')
            with open('./1.txt', mode='r') as file:
                while True:
                    line = file.readline().strip()
                    if line:
                        req_msg = name + ',' + password
                        if line == req_msg:
                            print('登陆成功')
                            status = 1
                            msg = F(*args, **kwargs)
                            return msg
                    else:
                        break
                if status == 0:
                    print('用户名密码不正确')
                return False
        else:
            msg = F(*args, **kwargs)
        return msg
    return inner

@wrapper
def index_1():
    print("首页一")

@wrapper
def index_2():
    print('首页二')

@wrapper
def index_3():
    print('首页三')

#print(register())#注册,成功也不用重新登录
index_1()
index_3()
index_2()