• Python函数07/有参装饰器/多个装饰器装饰一个函数


    Python函数07/有参装饰器/多个装饰器装饰一个函数

    内容大纲

    1.有参装饰器

    2.多个装饰器装饰一个函数

    1.有参装饰器

    # def auth(argv):
    #     def wrapper(func):
    #         def inner(*args,**kwargs):
    #             func(*args,**kwargs)
    #         return inner
    #     return wrapper
    
    
    # login_dic = {
    #     "username": None,
    #     "flag": False
    # }
    # def auth(argv): # argv == foo
    #     def wrapper(func):
    #         def inner(*args,**kwargs):
    #             if login_dic["flag"]:
    #                 func(*args,**kwargs)
    #             else:
    #                 if argv == "QQ":
    #                     user = input("username:")
    #                     pwd = input("password:")
    #                     if user == "alex" and pwd == "alex123":  # qq
    #                         login_dic["flag"] = True
    #                         login_dic["username"] = user
    #                         func(*args,**kwargs)
    #                     else:
    #                         print("用户名或密码错误!")
    #                 elif argv == "微信":
    #                     user = input("username:")
    #                     pwd = input("password:")
    #                     if user == "1351101501" and pwd == "alex":  # 微信
    #                         login_dic["flag"] = True
    #                         login_dic["username"] = user
    #                         func(*args, **kwargs)
    #                     else:
    #                         print("用户名或密码错误!")
    #                 elif argv == "抖音":
    #                     user = input("username:")
    #                     pwd = input("password:")
    #                     if user == "alexdsb" and pwd == "alex":  # 抖音
    #                         login_dic["flag"] = True
    #                         login_dic["username"] = user
    #                         func(*args, **kwargs)
    #                     else:
    #                         print("用户名或密码错误!")
    #                 else:
    #                     user = input("username:")
    #                     pwd = input("password:")
    #                     if user == "alexdsb@dsb.com" and pwd == "alex":  # 邮箱
    #                         login_dic["flag"] = True
    #                         login_dic["username"] = user
    #                         func(*args, **kwargs)
    #                     else:
    #                         print("用户名或密码错误!")
    #
    #         return inner
    #     return wrapper
    #
    # # 错误的案例
    # @auth # foo = auth(foo)
    # def foo():
    #     print("这是一个被装饰的函数")
    #
    # foo()
    
    
    login_dic = {
        "username": None,
        "flag": False
    }
    # 正确的案例
    msg = """
    QQ
    微信
    抖音
    邮箱
    请输入您要选择登陆的app:
    """
    chose = input(msg).upper()
    
    def auth(argv):
        def wrapper(func):
            def inner(*args,**kwargs):
                if login_dic["flag"]:
                    func(*args,**kwargs)
                else:
                    if argv == "QQ":
                        print("欢迎登陆QQ")
                        user = input("username:")
                        pwd = input("password:")
                        if user == "alex" and pwd == "alex123":  # qq
                            login_dic["flag"] = True
                            login_dic["username"] = user
                            func(*args,**kwargs)
                        else:
                            print("用户名或密码错误!")
                    elif argv == "微信":
                        print("欢迎登陆微信")
                        user = input("username:")
                        pwd = input("password:")
                        if user == "1351101501" and pwd == "alex":  # 微信
                            login_dic["flag"] = True
                            login_dic["username"] = user
                            func(*args, **kwargs)
                        else:
                            print("用户名或密码错误!")
                    elif argv == "抖音":
                        print("来了,老弟!")
                        user = input("username:")
                        pwd = input("password:")
                        if user == "alexdsb" and pwd == "alex":  # 抖音
                            login_dic["flag"] = True
                            login_dic["username"] = user
                            func(*args, **kwargs)
                        else:
                            print("用户名或密码错误!")
                    else:
                        print("欢迎登陆dab邮箱")
                        user = input("username:")
                        pwd = input("password:")
                        if user == "alexdsb@dsb.com" and pwd == "alex":  # 邮箱
                            login_dic["flag"] = True
                            login_dic["username"] = user
                            func(*args, **kwargs)
                        else:
                            print("用户名或密码错误!")
            return inner
        return wrapper
    @auth("QQ")
    def foo():
        print("这是一个被装饰的函数")
    
    # wrapper = auth(chose)
    # foo = wrapper(foo)
    foo()
    
    
    
    """
    # @auth(chose) 相等于以下两行代码的解构
    # wrapper = auth(chose)
    # foo = wrapper(foo)
    """
    

    2.多个装饰器装饰一个函数

    def wrapper1(func):
        def inner1(*args,**kwargs):
            print(1)
            func(*args,**kwargs)
            print(11)
        return inner1
    
    def wrapper2(func):  # func == foo
        def inner2(*args,**kwargs):
            print(11)
            func(*args, **kwargs)
            print(22)
        return inner2
    
    def wrapper3(func):
        def inner3(*args,**kwargs):
            print(3)
            func(*args, **kwargs)
            print(33)
        return inner3
    
    # @wrapper1  # 1 11
    # @wrapper3  # 3 33
    # @wrapper2  #  8 22
    
    # def foo():
    #     print(8)
    
    # foo = wrapper2(foo)  # foo == inner2
    # foo = wrapper3(foo)  # inner3 = wrapper3(inner2)
    # foo = wrapper1(foo)  # inner1 = wrapper1(inner3)
    # foo()                # inner1()
    
    
    # foo = wrapper3(foo)  # foo == inner3
    # foo = wrapper2(foo)  # foo = wrapper2(inner3)  foo == inner2
    # foo = wrapper1(foo)  # foo = wrapper1(inner2)
    
    
    被装饰的函数正上方有多个装饰器,先执行离被装饰函数最近的装饰器
    

    1563978582335

    1564013988963

    1564014107225

    3.今日总结

    # 1.有参装饰器
    # 在装饰器的基础上再套一层
    # @auth("QQ")
    # def foo():
    #     pass
    # f = auth("qq")
    # foo = f(foo)
    # foo()
    
    
    # 2.多个装饰器装饰一个函数
    # def wrapper1(func):
    #     def inner1(*args,**kwargs):
    #         print(1)
    #         func(*args,**kwargs)
    #         print(11)
    #     return inner1
    #
    # def wrapper2(func):  # func == foo
    #     def inner2(*args,**kwargs):
    #         func(*args, **kwargs)
    #         print(22)
    #     return inner2
    #
    # def wrapper3(func):
    #     def inner3(*args,**kwargs):
    #         print(3)
    #         func(*args, **kwargs)
    #         print(33)
    #     return inner3
    
    # @wrapper1  # 1 11
    # @wrapper3  # 3 33
    # @wrapper2  #  8 22
    
    # def foo():
    #     print(8)
    
    先执行离被装饰的函数最近的语法糖
    小技巧:进入装饰器从上往下,走到最会一个装饰器执行被装饰的函数,退出装饰器从下往上走
    

    3.今日练习

    1.请实现一个装饰器,限制该函数被调用的频率,如10秒一次(面试题)
    # import time
    # def wrapper(f):
    #     t = 0
    #     def inner(*args,**kwargs):
    #         nonlocal t
    #         if time.time()-t >= 10:
    #             t = time.time()
    #             f(*args,**kwargs)
    #         else:
    #             print("被限制了")
    #     return inner
    # @wrapper
    # def func():
    #     print("被装饰函数")
    # while True:
    #     func()
    #     time.sleep(2)
    #     func()
    #     time.sleep(2)
    #     func()
    #     time.sleep(2)
    #
    # 2.请写出下列代码片段的输出结果:
    # def say_hi(func):
    #     def wrapper(*args,**kwargs):
    #         print("HI")
    #         ret=func(*args,**kwargs)
    #         print("BYE")
    #         return ret
    #     return wrapper
    #
    # def say_yo(func):
    #     def wrapper(*args,**kwargs):
    #         print("Yo")
    #         return func(*args,**kwargs)
    #     return wrapper
    # @say_hi
    # @say_yo
    # def func():
    #     print("ROCK&ROLL")
    # func()
    # HI
    # Yo
    # ROCK&ROLL
    # BYE
    #
    3.编写装饰器完成下列需求:
    # 用户有两套账号密码,一套为京东账号密码,一套为淘宝账号密码分别保存在两个文件中。
    # 设置四个函数,分别代表 京东首页,京东超市,淘宝首页,淘宝超市。
    # 启动程序后,呈现用户的选项为:
    #   1,京东首页
    #   2,京东超市
    #   3,淘宝首页
    #   4,淘宝超市
    #   5,退出程序
    # 四个函数都加上认证功能,用户可任意选择,用户选择京东超市或者京东首页,只要输入一次京东账号和密码并成功,
    # 则这两个函数都可以任意访问;用户选择淘宝超市或者淘宝首页,只要输入一次淘宝账号和密码并成功,则这两个函数都可以任意访问.
    # 相关提示:用带参数的装饰器。装饰器内部加入判断,验证不同的账户密码。
    # msg = """
    #   1,京东首页
    #   2,京东超市
    #   3,淘宝首页
    #   4,淘宝超市
    #   5,退出程序
    #   请选择序号>>>:
    # """
    # login_dic = {
    #     "jd":False,
    #     "tb":False
    # }
    # def auth(argv):
    #     def wrapper(f):
    #         def inner(*args,**kwargs):
    #             if login_dic[argv]:
    #                 f(*args,**kwargs)
    #             else:
    #                 print(f"{argv} login")
    #                 user = input("请输入姓名:")
    #                 psd = input("请输入密码:")
    #                 with open(argv,"r",encoding="utf-8") as f1:
    #                     for i in f1:
    #                         username,password = i.strip().split(":")
    #                         if user == username and psd == password:
    #                             login_dic[argv] = True
    #                             print("登录成功!")
    #                             return f(*args,**kwargs)
    #                         else:
    #                             print("账号或密码错误")
    #                             return inner()
    #         return inner
    #     return wrapper
    # 
    # @auth("jd")
    # def jd_index():
    #     print("这是京东主页")
    # 
    # @auth("jd")
    # def jd_shopping():
    #     print("这是京东超市")
    # 
    # @auth("tb")
    # def tb_index():
    #     print("这是淘宝主页")
    # 
    # @auth("tb")
    # def tb_shopping():
    #     print("这是淘宝超市")
    # 
    # dic = {"1":jd_index ,"2":jd_shopping ,"3":tb_index,"4":tb_shopping, "5":exit}
    # while True:
    #     choose = input(msg)
    #     if choose in dic:
    #         dic[choose]()
    #     else:
    #         print("请正确输入")
    #
    4.给l1 = [1,1,2,2,3,3,6,6,5,5,2,2]去重,不能使用set集合(面试题)。
    # l1 = [1,1,2,2,3,3,6,6,5,5,2,2]
    # lst = []
    # for i in l1:
    #     if i not in lst:
    #         lst.append(i)
    # print(lst)
    #
    5.用递归函数完成斐波那契数列(面试题):
    # 斐波那契数列:1,1,2,3,5,8,13,21..........(第三个数为前两个数的和,但是最开始的1,1是特殊情况,可以单独讨论)
    # lst = []
    # def func(num):
    #     if num == 0:
    #         ret = 1
    #     elif num == 1:
    #         ret =1
    #     else:
    #         ret = (func(num-2)+func(num-1))
    #     return ret
    # num = int(input(">>>"))
    # n = 0
    # while func(n) < num:
    #     lst.append(func(n))
    #     n += 1
    # print(lst)
    
    6.用户输入序号获取对应的斐波那契数字:比如输入6,返回的结果为8.
    # def func(num):
    #     if num == 0:
    #         ret = 1
    #     elif num == 1:
    #         ret =1
    #     else:
    #         ret = (func(num-2)+func(num-1))
    #     return ret
    # print(func(5))
    7.请实现一个装饰器,限制该函数被调用的频率,如10秒一次(面试题)
    # import time
    # def wrapper(f):
    #     t = 0
    #     def inner(*args,**kwargs):
    #         nonlocal t
    #         if time.time()-t >= 10:
    #             t = time.time()
    #             f()
    #         else:
    #             print("被限制了")
    #     return inner
    # @wrapper
    # def func():
    #     print("被装饰函数")
    # func()
    
    
  • 相关阅读:
    团队活动
    实力提升
    软工人必须要知道的几个工具
    博客/论坛:(技术分享)
    CSS怎样设置多个字体,设置多个字体的时候要注意什么
    canvas绘制bitmap全部填充(当bitmap的宽高小于绘制区域的时候)
    CSS字体
    weditor元素定位异常
    python ImportError: C extension: DLL load failed while importing strptim
    python:导入不同路径下相同名称的模块
  • 原文地址:https://www.cnblogs.com/liubing8/p/11244385.html
Copyright © 2020-2023  润新知