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

内容大纲

1.有参装饰器

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

1.有参装饰器

  1. # def auth(argv):
  2. # def wrapper(func):
  3. # def inner(*args,**kwargs):
  4. # func(*args,**kwargs)
  5. # return inner
  6. # return wrapper
  7. # login_dic = {
  8. # "username": None,
  9. # "flag": False
  10. # }
  11. # def auth(argv): # argv == foo
  12. # def wrapper(func):
  13. # def inner(*args,**kwargs):
  14. # if login_dic["flag"]:
  15. # func(*args,**kwargs)
  16. # else:
  17. # if argv == "QQ":
  18. # user = input("username:")
  19. # pwd = input("password:")
  20. # if user == "alex" and pwd == "alex123": # qq
  21. # login_dic["flag"] = True
  22. # login_dic["username"] = user
  23. # func(*args,**kwargs)
  24. # else:
  25. # print("用户名或密码错误!")
  26. # elif argv == "微信":
  27. # user = input("username:")
  28. # pwd = input("password:")
  29. # if user == "1351101501" and pwd == "alex": # 微信
  30. # login_dic["flag"] = True
  31. # login_dic["username"] = user
  32. # func(*args, **kwargs)
  33. # else:
  34. # print("用户名或密码错误!")
  35. # elif argv == "抖音":
  36. # user = input("username:")
  37. # pwd = input("password:")
  38. # if user == "alexdsb" and pwd == "alex": # 抖音
  39. # login_dic["flag"] = True
  40. # login_dic["username"] = user
  41. # func(*args, **kwargs)
  42. # else:
  43. # print("用户名或密码错误!")
  44. # else:
  45. # user = input("username:")
  46. # pwd = input("password:")
  47. # if user == "alexdsb@dsb.com" and pwd == "alex": # 邮箱
  48. # login_dic["flag"] = True
  49. # login_dic["username"] = user
  50. # func(*args, **kwargs)
  51. # else:
  52. # print("用户名或密码错误!")
  53. #
  54. # return inner
  55. # return wrapper
  56. #
  57. # # 错误的案例
  58. # @auth # foo = auth(foo)
  59. # def foo():
  60. # print("这是一个被装饰的函数")
  61. #
  62. # foo()
  63. login_dic = {
  64. "username": None,
  65. "flag": False
  66. }
  67. # 正确的案例
  68. msg = """
  69. QQ
  70. 微信
  71. 抖音
  72. 邮箱
  73. 请输入您要选择登陆的app:
  74. """
  75. chose = input(msg).upper()
  76. def auth(argv):
  77. def wrapper(func):
  78. def inner(*args,**kwargs):
  79. if login_dic["flag"]:
  80. func(*args,**kwargs)
  81. else:
  82. if argv == "QQ":
  83. print("欢迎登陆QQ")
  84. user = input("username:")
  85. pwd = input("password:")
  86. if user == "alex" and pwd == "alex123": # qq
  87. login_dic["flag"] = True
  88. login_dic["username"] = user
  89. func(*args,**kwargs)
  90. else:
  91. print("用户名或密码错误!")
  92. elif argv == "微信":
  93. print("欢迎登陆微信")
  94. user = input("username:")
  95. pwd = input("password:")
  96. if user == "1351101501" and pwd == "alex": # 微信
  97. login_dic["flag"] = True
  98. login_dic["username"] = user
  99. func(*args, **kwargs)
  100. else:
  101. print("用户名或密码错误!")
  102. elif argv == "抖音":
  103. print("来了,老弟!")
  104. user = input("username:")
  105. pwd = input("password:")
  106. if user == "alexdsb" and pwd == "alex": # 抖音
  107. login_dic["flag"] = True
  108. login_dic["username"] = user
  109. func(*args, **kwargs)
  110. else:
  111. print("用户名或密码错误!")
  112. else:
  113. print("欢迎登陆dab邮箱")
  114. user = input("username:")
  115. pwd = input("password:")
  116. if user == "alexdsb@dsb.com" and pwd == "alex": # 邮箱
  117. login_dic["flag"] = True
  118. login_dic["username"] = user
  119. func(*args, **kwargs)
  120. else:
  121. print("用户名或密码错误!")
  122. return inner
  123. return wrapper
  124. @auth("QQ")
  125. def foo():
  126. print("这是一个被装饰的函数")
  127. # wrapper = auth(chose)
  128. # foo = wrapper(foo)
  129. foo()
  130. """
  131. # @auth(chose) 相等于以下两行代码的解构
  132. # wrapper = auth(chose)
  133. # foo = wrapper(foo)
  134. """

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

  1. def wrapper1(func):
  2. def inner1(*args,**kwargs):
  3. print(1)
  4. func(*args,**kwargs)
  5. print(11)
  6. return inner1
  7. def wrapper2(func): # func == foo
  8. def inner2(*args,**kwargs):
  9. print(11)
  10. func(*args, **kwargs)
  11. print(22)
  12. return inner2
  13. def wrapper3(func):
  14. def inner3(*args,**kwargs):
  15. print(3)
  16. func(*args, **kwargs)
  17. print(33)
  18. return inner3
  19. # @wrapper1 # 1 11
  20. # @wrapper3 # 3 33
  21. # @wrapper2 # 8 22
  22. # def foo():
  23. # print(8)
  24. # foo = wrapper2(foo) # foo == inner2
  25. # foo = wrapper3(foo) # inner3 = wrapper3(inner2)
  26. # foo = wrapper1(foo) # inner1 = wrapper1(inner3)
  27. # foo() # inner1()
  28. # foo = wrapper3(foo) # foo == inner3
  29. # foo = wrapper2(foo) # foo = wrapper2(inner3) foo == inner2
  30. # foo = wrapper1(foo) # foo = wrapper1(inner2)
  31. 被装饰的函数正上方有多个装饰器,先执行离被装饰函数最近的装饰器

3.今日总结

  1. # 1.有参装饰器
  2. # 在装饰器的基础上再套一层
  3. # @auth("QQ")
  4. # def foo():
  5. # pass
  6. # f = auth("qq")
  7. # foo = f(foo)
  8. # foo()
  9. # 2.多个装饰器装饰一个函数
  10. # def wrapper1(func):
  11. # def inner1(*args,**kwargs):
  12. # print(1)
  13. # func(*args,**kwargs)
  14. # print(11)
  15. # return inner1
  16. #
  17. # def wrapper2(func): # func == foo
  18. # def inner2(*args,**kwargs):
  19. # func(*args, **kwargs)
  20. # print(22)
  21. # return inner2
  22. #
  23. # def wrapper3(func):
  24. # def inner3(*args,**kwargs):
  25. # print(3)
  26. # func(*args, **kwargs)
  27. # print(33)
  28. # return inner3
  29. # @wrapper1 # 1 11
  30. # @wrapper3 # 3 33
  31. # @wrapper2 # 8 22
  32. # def foo():
  33. # print(8)
  34. 先执行离被装饰的函数最近的语法糖
  35. 小技巧:进入装饰器从上往下,走到最会一个装饰器执行被装饰的函数,退出装饰器从下往上走

3.今日练习

  1. 1.请实现一个装饰器,限制该函数被调用的频率,如10秒一次(面试题)
  2. # import time
  3. # def wrapper(f):
  4. # t = 0
  5. # def inner(*args,**kwargs):
  6. # nonlocal t
  7. # if time.time()-t >= 10:
  8. # t = time.time()
  9. # f(*args,**kwargs)
  10. # else:
  11. # print("被限制了")
  12. # return inner
  13. # @wrapper
  14. # def func():
  15. # print("被装饰函数")
  16. # while True:
  17. # func()
  18. # time.sleep(2)
  19. # func()
  20. # time.sleep(2)
  21. # func()
  22. # time.sleep(2)
  23. #
  24. # 2.请写出下列代码片段的输出结果:
  25. # def say_hi(func):
  26. # def wrapper(*args,**kwargs):
  27. # print("HI")
  28. # ret=func(*args,**kwargs)
  29. # print("BYE")
  30. # return ret
  31. # return wrapper
  32. #
  33. # def say_yo(func):
  34. # def wrapper(*args,**kwargs):
  35. # print("Yo")
  36. # return func(*args,**kwargs)
  37. # return wrapper
  38. # @say_hi
  39. # @say_yo
  40. # def func():
  41. # print("ROCK&ROLL")
  42. # func()
  43. # HI
  44. # Yo
  45. # ROCK&ROLL
  46. # BYE
  47. #
  48. 3.编写装饰器完成下列需求:
  49. # 用户有两套账号密码,一套为京东账号密码,一套为淘宝账号密码分别保存在两个文件中。
  50. # 设置四个函数,分别代表 京东首页,京东超市,淘宝首页,淘宝超市。
  51. # 启动程序后,呈现用户的选项为:
  52. # 1,京东首页
  53. # 2,京东超市
  54. # 3,淘宝首页
  55. # 4,淘宝超市
  56. # 5,退出程序
  57. # 四个函数都加上认证功能,用户可任意选择,用户选择京东超市或者京东首页,只要输入一次京东账号和密码并成功,
  58. # 则这两个函数都可以任意访问;用户选择淘宝超市或者淘宝首页,只要输入一次淘宝账号和密码并成功,则这两个函数都可以任意访问.
  59. # 相关提示:用带参数的装饰器。装饰器内部加入判断,验证不同的账户密码。
  60. # msg = """
  61. # 1,京东首页
  62. # 2,京东超市
  63. # 3,淘宝首页
  64. # 4,淘宝超市
  65. # 5,退出程序
  66. # 请选择序号>>>:
  67. # """
  68. # login_dic = {
  69. # "jd":False,
  70. # "tb":False
  71. # }
  72. # def auth(argv):
  73. # def wrapper(f):
  74. # def inner(*args,**kwargs):
  75. # if login_dic[argv]:
  76. # f(*args,**kwargs)
  77. # else:
  78. # print(f"{argv} login")
  79. # user = input("请输入姓名:")
  80. # psd = input("请输入密码:")
  81. # with open(argv,"r",encoding="utf-8") as f1:
  82. # for i in f1:
  83. # username,password = i.strip().split(":")
  84. # if user == username and psd == password:
  85. # login_dic[argv] = True
  86. # print("登录成功!")
  87. # return f(*args,**kwargs)
  88. # else:
  89. # print("账号或密码错误")
  90. # return inner()
  91. # return inner
  92. # return wrapper
  93. #
  94. # @auth("jd")
  95. # def jd_index():
  96. # print("这是京东主页")
  97. #
  98. # @auth("jd")
  99. # def jd_shopping():
  100. # print("这是京东超市")
  101. #
  102. # @auth("tb")
  103. # def tb_index():
  104. # print("这是淘宝主页")
  105. #
  106. # @auth("tb")
  107. # def tb_shopping():
  108. # print("这是淘宝超市")
  109. #
  110. # dic = {"1":jd_index ,"2":jd_shopping ,"3":tb_index,"4":tb_shopping, "5":exit}
  111. # while True:
  112. # choose = input(msg)
  113. # if choose in dic:
  114. # dic[choose]()
  115. # else:
  116. # print("请正确输入")
  117. #
  118. 4.l1 = [1,1,2,2,3,3,6,6,5,5,2,2]去重,不能使用set集合(面试题)。
  119. # l1 = [1,1,2,2,3,3,6,6,5,5,2,2]
  120. # lst = []
  121. # for i in l1:
  122. # if i not in lst:
  123. # lst.append(i)
  124. # print(lst)
  125. #
  126. 5.用递归函数完成斐波那契数列(面试题):
  127. # 斐波那契数列:1,1,2,3,5,8,13,21..........(第三个数为前两个数的和,但是最开始的1,1是特殊情况,可以单独讨论)
  128. # lst = []
  129. # def func(num):
  130. # if num == 0:
  131. # ret = 1
  132. # elif num == 1:
  133. # ret =1
  134. # else:
  135. # ret = (func(num-2)+func(num-1))
  136. # return ret
  137. # num = int(input(">>>"))
  138. # n = 0
  139. # while func(n) < num:
  140. # lst.append(func(n))
  141. # n += 1
  142. # print(lst)
  143. 6.用户输入序号获取对应的斐波那契数字:比如输入6,返回的结果为8.
  144. # def func(num):
  145. # if num == 0:
  146. # ret = 1
  147. # elif num == 1:
  148. # ret =1
  149. # else:
  150. # ret = (func(num-2)+func(num-1))
  151. # return ret
  152. # print(func(5))
  153. 7.请实现一个装饰器,限制该函数被调用的频率,如10秒一次(面试题)
  154. # import time
  155. # def wrapper(f):
  156. # t = 0
  157. # def inner(*args,**kwargs):
  158. # nonlocal t
  159. # if time.time()-t >= 10:
  160. # t = time.time()
  161. # f()
  162. # else:
  163. # print("被限制了")
  164. # return inner
  165. # @wrapper
  166. # def func():
  167. # print("被装饰函数")
  168. # func()

Python函数07/有参装饰器/多个装饰器装饰一个函数的更多相关文章

  1. 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。

    题目: 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数,该函数能够生成1-10的随机数. 思路: 假如已知一个函数能够生成1-49的随机数,那么如何以此生成1-10的随机数呢? 解法 ...

  2. python进阶04 装饰器、描述器、常用内置装饰器

    python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...

  3. Python全栈工程师(函数的传参)

     ParisGabriel   感谢 大家的支持                                                               每天坚持 一天一篇 点个订 ...

  4. Python笔记_第四篇_高阶编程_高阶函数_1.map和reduce

    1. map()函数: 原型:map(fn,lsd) 参数1是函数 参数2是序列 功能:将传入的函数一次作用在序列中的每一个元素.并把结果作为一个新的Iterator返回.其实map函数就是一个for ...

  5. Python定义一个函数

    Python函数:实现某种功能的代码段 定义一个函数需要遵循的规则: 1.使用 def 关键字 函数名和( ),括号内可以有形参 匿名函数使用 lambda 关键字定义 2.任何传入参数和自变量必须放 ...

  6. js中如何在一个函数里面执行另一个函数

    1.js中如何在函数a里面执行函数b function a(参数c){ b(); } function b(参数c){ } 方法2: <script type="text/javasc ...

  7. js new一个函数和直接调用函数的区别

    用new和调用一个函数的区别:如果函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象,而如果这个函数的返回值是一个引用类型(Object.Arr ...

  8. js new一个函数和直接调用函数的差别

    用new和调用一个函数的差别:假设函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象.而假设这个函数的返回值是一个引用类型(Object.Arr ...

  9. vue中data必须是一个函数

    前端面试时经常被问到:“组建中data为什么是函数”? 答案就是:在组件中data必须是一个函数,这样的话,每个实例可以维护一份被返回对象的独立拷贝.

随机推荐

  1. 在VisualStudio中为GUI程序添加console

    1.使用WINDOWS提供的一系列ReadConsole,WriteConsole等API来完成这个功能,具体参见MSDN HANDLE hOut = GetStdHandle(STD_OUTPUT_ ...

  2. (九)logback.xml文件配置(按时间、文件大小和log名称生成日志)

    原文链接:https://www.cnblogs.com/hhhshct/p/9084036.html rollingPolicy 设置:<rollingPolicy class="c ...

  3. 使用python求解向量值函数的雅各比(Jacobian)矩阵

    考虑一个向量值函数$R^m \rightarrow R^n$,即$\textbf{y} = f(\textbf{x})$,它的雅各比(Jacobian)矩阵定义如下. 下面记录下一段使用python求 ...

  4. HashSet扩容机制在时间和空间上的浪费,远大于你的想象

    一:背景 1. 讲故事 自从这个纯内存项目进了大客户之后,搞得我现在对内存和CPU特别敏感,跑一点数据内存几个G的上下,特别没有安全感,总想用windbg抓几个dump看看到底是哪一块导致的,是我的代 ...

  5. 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  6. 你想不到的沙雕,10行代码Python实现GIF图倒放,每天的快乐源泉

    前言 GIF图现在已经融入了我们的日常网络生活,微信群.QQ群.朋友圈......一言不合就斗图,你怕了吗?不用担心,只要学会了Python之GIF倒放技能,你就是“斗图王”. 咱们直接开始本文的内容 ...

  7. drf之序列化组件(一):Serializer

    序列化组件:Serializer.ModelSerializer.ListModelSerializer Serializer  偏底层  ModelSerializer       重点  List ...

  8. (一)、Java内存模型

    简述 Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM),来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效 ...

  9. SpringBoot——项目启动时读取配置及初始化资源

    介绍   在开发过程中,我们有时候会遇到非接口调用而出发程序执行任务的一些场景,比如我们使用quartz定时框架通过配置文件来启动定时任务时,或者一些初始化资源场景等触发的任务执行场景. 方法一:注解 ...

  10. Java 多线程基础(十二)生产者与消费者

    Java 多线程基础(十二)生产者与消费者 一.生产者与消费者模型 生产者与消费者问题是个非常典型的多线程问题,涉及到的对象包括“生产者”.“消费者”.“仓库”和“产品”.他们之间的关系如下: ①.生 ...