zoukankan      html  css  js  c++  java
  • Python 3 学习笔记(六)----装饰器

    一、定义

    装饰器本质是函数,装饰其他函数,就是为其它函数添加附加功能

    二、装饰器原则

    1.不能修改被装饰的函数的源代码

    2.不能修改被装饰的函数的调用方式

    三、实现装饰器的必要知识

    1.函数即是变量

     1 # def foo():
     2 #     print("in the foo")
     3 #     bar()    #bar未定义
     4 # foo()
     5 
     6 
     7 # def bar():
     8 #     print("int the bar")
     9 # def foo():
    10 #     print("in the foo")
    11 #     bar()
    12 # foo()
    13 
    14 
    15 # def foo():
    16 #     print("in the foo")
    17 #     bar()
    18 # def bar():
    19 #     print("int the bar")
    20 # foo()
    1 def foo():
    2     print("in the foo")
    3     bar()
    4 foo()
    5 def bar():  #在调用后定义不会执行
    6     print("int the bar")

    2.高阶函数(高阶函数的两种表达方式)

    2.1把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

     1 import time
     2 
     3  def bar():
     4      time.sleep(3)
     5      print("in the bar")
     6 
     7  def test1(func):
     8      start_time = time.time()
     9      func()
    10      stop_time = time.time()
    11      print("the func run time is %s" %(stop_time-start_time))
    12  test1(bar)

    2.2返回值中包含函数名

     1 import time
     2 def bar():
     3     time.sleep(3)
     4     print("in the bar")
     5 def test2(func):
     6     print(func)
     7     return func#返回为内存地址
     8 
     9 #print(test2(bar))
    10 # t=test2(bar)
    11 # t() #run bar
    12 bar=test2(bar)
    13 bar() #返回的内存地址加上()就可以执行

    3.嵌套函数

     1 x=0
     2 def a():
     3     x=1
     4     def b():
     5         x=2
     6         def c():
     7             x=3
     8             print(x)
     9         c()
    10     b() #此处如果不执行b(),那么函数相当于什么都没干,因为没有print
    11 a()

    四、装饰器=高阶函数+嵌套函数

     1 import time
     2 
     3 def timer(func):  #timer(test)  func=test
     4     def deco():
     5         start_time = time.time()
     6         func()   #此处运行被装饰函数test
     7         stop_time = time.time()
     8         print("func run time is %s" %(stop_time-start_time))
     9     return deco  #返回deco的内存地址
    10 
    11 
    12 @timer   #相当于timer=timer(test),装饰器永远放在被装饰的函数前
    13 def test():
    14     time.sleep(3)
    15     print("this is test")
    16 
    17 test()

    五、如果装饰器的函数中包含参数

     1 import time
     2 
     3 def timer(func):
     4     def deco(*args,**kwargs):  #*args,**kwargs代表参数不确定的意思
     5         start_time=time.time()
     6         func(*args,**kwargs)
     7         stop_time=time.time()
     8         print("in the run time is %s" %(stop_time-start_time))
     9     return deco
    10 
    11 @timer   # test2 = timer(test2) = deco    test2(name) = deco(name)
    12 def test2(age,name,job):
    13     time.sleep(1)
    14     print("test2:",age,name,job)
    15 
    16 test2(23,"Irlo","seller")

    六、装饰器的使用实例

    假设为网页添加登陆验证

     1 user,pasd = "Irlo","12345"
     2 def auth(auth_type):
     3     print("auth func is",auth_type)
     4     def type(func):
     5         def wrapper():
     6             if auth_type == "local":
     7                 username = input("username:").strip()  #strip移除字符串首尾指定的字符(默认为空格)
     8                 password = input("password:").strip()
     9                 if user==username and pasd==password:
    10                     print("33[1;32;1mauthority of account33[0m") #高亮显示的格式(33[显示方式;前景色;背景色m)
    11                     res=func()  #将结果赋值给一个变量才能在之后调用home有结果
    12                     print("after authentication")
    13                     return res  #如果不返回,相当于执行完就结束了,没有返回值是一个空值
    14                 else:
    15                     print(" invalid username or password ")
    16             elif auth_type == "ldap":
    17                 print("I just know local,fuck off")
    18         return wrapper
    19     return type
    20 
    21 def index():
    22     print("welcome to index page")
    23 
    24 @auth(auth_type = "local")
    25 def home():
    26     print("welcome to home page")
    27     return "from home"
    28 
    29 @auth(auth_type = "ldap")
    30 def bbs():
    31     print("welcome to bbs page")
    32 
    33 index()
    34 print(home()) #调用home的时候相当于是调用wrapper
    35 home()
    36 bbs()
  • 相关阅读:
    P1168 中位数(对顶堆)
    P2341 [HAOI2006]受欢迎的牛
    P1967 货车运输
    树状数组的神操作QAQ
    P1063 能量项链
    P1429 平面最近点对(加强版)
    P2571 [SCOI2010]传送带
    4 Values whose Sum is 0
    UVA529 Addition Chains
    UVA307 Sticks
  • 原文地址:https://www.cnblogs.com/consort/p/7492507.html
Copyright © 2011-2022 走看看