装饰器

#装饰器,语法糖 @函数名
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()

 

#练习2:给函数加日志,记录函数的名称、时间
import time

def wrapper5(F):
    def inner(*args, **kwargs):
        with open("log", 'a', encoding='utf-8') as f1:
            f1.write("%s 函数在  %s 执行\n" % (F.__name__, time.asctime()))
        ret = F(*args, **kwargs)
        return ret
    return inner

@wrapper5
def test1():
    pass

@wrapper5
def test2():
    pass

test1()
test2()


#练习3:设置登陆,分两个平台,相同平台登陆成功可成功访问,不同平台需重新登陆,成功则平台下所有页面均可访问,失败三次结束
status_list = {'name': None, 'user_status': False, 'user2_status': False}

def login_out(ags):
    def login(F):
        @wraps(F)
        def inner(*args, **kwargs):
            if status_list['%s_status' % ags]:
                ret = F()
                return ret
            else:
                status_list['user_status'] = False
                status_list['user2_status'] = False
                i = 1
                while i < 4:
                    username = input('用户名:').strip()
                    password = input('密码:').strip()
                    with open("%s_info" % (ags), encoding='utf-8') as f1:
                        for line in f1:
                            user_list = line.strip().split(',')
                            if username == user_list[0] and password == user_list[1]:
                                print("登陆成功")
                                status_list['name'] = username
                                status_list['%s_status' % ags] = True
                                ret = F()
                                return ret
                    print("用户名或密码错误,还剩%s次" % (3-i))
                    i += 1
        return inner
    return login

@login_out('user')
def index():
    print("首页")
    print("欢迎%s" % (status_list['name']))

@login_out('user2')
def knowledge():
    print("知识区欢迎%s" % (status_list['name']))

@login_out('user2')
def kichiku():
    print("鬼畜区欢迎%s" % (status_list['name']))


def choose():
    while True:
        dic_s = {
            1: index,
            2: knowledge,
            3: kichiku
        }
        print("""
        1、看剧
        2、听歌
        3、学习
        """)
        ch = input("请选择:").strip()
        if ch.isdigit():
            ch = int(ch)
            if 0 < ch <= len(dic_s):
                dic_s[ch]()
            else:
                print("选项有误")
        else:
            print("输入有误")

choose()

 

posted @ 2022-04-14 19:23  尐少  阅读(23)  评论(0)    收藏  举报