zoukankan      html  css  js  c++  java
  • python装饰器详述

    装饰器: 
     可以解释为函数,装饰器就是装饰函数;
     功能:装饰器本身是函数,用来装饰其他函数的。
           就是为其他函数添加附加功能。
       
     例1: 
     def test1():
        pass
     def test2():
        pass
     test1()
     test2()
     
     此时需要给源码test1和test2添加记录日志功能。
     
     函数表示:
    def logger():
      print("logging....")
    def test1():
      pass
      logger()
    def test2():
      pass
      logger()
      
     test1()
     test2()
     这样相当于修改整个源代码(上线源代码原则是不能修改)不符合装饰器要求。
     
     
     装饰器的原则:
     1. 不能修改被装饰的函数的源代码;
     2. 不能修改被装饰的函数的调用方式;
     
     实现装饰器知识储备:
     1. 函数即"变量"
     2. 高阶函数
      a. 把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加新功能);
      b. 返回值包含函数名;
     
    例2:
     def bar():
      print("in the bas.......")
    def test1(func):
      print(func)
      func()                                                 #加小括号即表示运行;
       
    test1(bar)
      
      输出:
      <function bar at 0x03B5BA50>              #内存地址
      in the bas.......     
     
    例3:
     import time
    def bar():                          #源代码
      time.sleep(3)
      print("in the bas.......")
       
    def test1(func):
      start_time = time.time()
      func()
      stop_time = time.time()
      print(" the func run time is %s" %(stop_time - start_time))
       
      #bar()                         #原调用方式
      test1(bar)                        #改变了调用方式
      
      输出:
      in the bas.......
      the func run time is 3.000096321105957
     
     
    例4:
    import time
    def bar():
      time.sleep(3)
      print("in the bas.......")
       
    def test2(func):
      print(func)
      return func
       
    print(test2(bar))               #将内存地址作为参数传输
      
       
      输出:
      <function bar at 0x0327BA50>       #返回bar内存地址 
      <function bar at 0x0327BA50>
     
    例5; 
    import time
    def bar():
      time.sleep(3)
      print("in the bas.......")
    def test2(func):
      print(func)               #类似加了新功能:
      return func
    bar = test2(bar)              #覆盖原来的bar(门牌号)
    bar()
     
    输出:
      <function bar at 0x0320BA50>
      in the bas.......
     
      注意:高阶函数是不能return 自己的
     
     3. 嵌套函数:
       在函数体内用def去定义一个函数,叫做函数的嵌套;
      
    嵌套函数1:
    def foo():
      print("in the foo")
      def bar():
        print("in the bar")
      bar()
    foo()
    输出:
    "in the foo"
    "in the bar"
     
    局部作用域和全局作用域的访问顺序:
    x = 0
    def grandpa():
      x=1
      def dad():
        x=2
        def son():
          x = 3
          print(x)
        son()
       dad()
    grandpa()              #调用;
       
     输出:3
      
      
     高阶函数+嵌套函数 =》装饰器:
     
     
    import time
    #高阶函数
    def timer(func):
      def deco():
        start_time = time.time()
        func()                                                                #高阶函数
        end_time = time.time()
        print(" the func run time is %s" %(end_time - start_time))
        return deco                                       #带有返回值的高阶函数
     
    @timer                                    #@timer  等于 test1 = timer(test1)
    def test1():
      time.sleep(3)
      print("in the test1......")
      
    @timer 
    def test2():
      time.sleep(3)
      print("in the test2......")
     
     #test1()               #源执行方式
     #test2()
     
     #deco(test1)
     #deco(test2)
     
     #test1 = timer(test1)
     #test2 = timer(test2)
     #test1()
     #test2()
     
     
     test1()                                          #执行的deco()    
     test2()
     
     
     单参数传输: 
    import time
    def timer(func):
      def deco(p1):
        start_time = time.time()
        func(p1)
        end_time = time.time()
        print(" the func run time is %s" % (end_time - start_time))
      return deco
     
    @timer                                             # test2 = timer(test2)=deco, 所以test()=deco()等于test(p1)=deco(p1)
    def test2(name):
      time.sleep(1)
      print("in the test2 -- %s......"% name)
     
     test2("brace")
     
     输出:
     in the test2 -- brace......
     the func run time is 1.0179989337921143
     
     
    多参数或不固定参数:
    import time
    def timer(func):
      def deco(*args, **kwargs):
        start_time = time.time()
        func(*args,**kwargs)
        end_time = time.time()
        print(" the func run time is %s" % (end_time - start_time))
      return deco
     
     @timer                                  
     def test():
      time.sleep(1)
      print("in the test1......")
     
     @timer                                  
      def test2(name,age):
      time.sleep(1)
      print("in the test2 -- %s......"% name)
      print("in the test2 -- %s......"% age)
     
     test1()
     test2("brace","12")
     
     输出:
     in the test1......
     the func run time is 1.0099728107452393
     in the test2 -- brace......
     in the test2 -- 12......
     the func run time is 1.020176649093628
     
     
     
    一个页面代表一个函数:
    100个页面相当100个函数:
     
    无返回值的装饰器:
    user = "brace"
    passwd = "123"
    def auth(func):
      def wrapper(*args,**kwargs):
        username = input("user name:").strip()
        password = input("pass word:").strip()
        if user = usernae and passwd = password:
          print("33[32;1mUser had passed authentication!33[0m")
          func(*args,**kwargs)                                                                          #相关于执行原函数
        else:
          exit(33[31;1minvalid username and password!33[0m)
      return wrapper
     
     def index():
      print("welcome to index page.....")
     
     @auth                                                                                                                     #home = auth(home)=wrapper的内存地址
     def home():
      print("welcome to index page.....")
     
     @auth 
     def bbs():
      print("welcome to index page.....")
      
     index()                                        #执行的是wrapper()
     home()
     bbs()
     
     
    带返回值的装饰器:
     user = "brace"
     passwd = "123"
     def auth(func):
      def wrapper(*args,**kwargs):
        username = input("user name:").strip()
        password = input("pass word:").strip()
        if user = usernae and passwd = password:
          print("33[32;1mUser had passed authentication!33[0m")
          res = func(*args,**kwargs)
          return res
          else:
          exit(33[31;1minvalid username and password!33[0m)
      return wrapper
     
     def index():
      print("welcome to index page.....")
     
     @auth
     def home():
      print("welcome to index page.....")
      return "form home"
     
     @auth 
     def bbs():
      print("welcome to index page.....")
      
     index()
     home()
     bbs()
     
     
    带参数的装饰器:装饰器带参数:
    user,passwd = "brace","1234"
    def auth(auth_type):
      print("auth type:", auth_type)
      def out_wrapper(func):
        print("out_wrapper func:",func)
        def wrapper(*args, **kwargs):
          print("wrapper args:", *args)
          print("wrapper kwargs:", **kwargs)
     
          if auth_type == "local":
            username = input("user name:").strip()
            password = input("pass word:").strip()
             if user == username and passwd == password :
              print("33[32;1mUser had passed authentication!33[0m")
              res = func(*args, **kwargs)
              return res
            else:
              exit("33[31;1minvalid username and password!33[0m")
          else:
            print("waiting for development......! ")
            res = func(*args, **kwargs)
            return res
        return wrapper
      return out_wrapper
      
     def index():
      print("welcome to index page.....")
     
     @auth(auth_type="local")
     def home(name):
      print("welcome to index page.....", name)
      return "form home"
     @auth(auth_type="ldap")
     def bbs():
      print("welcome to index page.....")
      
     输出: 
     auth type: local
     out_wrapper func: <function home at 0x02E0BAE0>
     auth type: ldap
     out_wrapper func: <function bbs at 0x02E0BA50>
     welcome to index page.....
     wrapper args: brace
     wrapper kwargs:
     user name:brace
     pass word:1234
     User had passed authentication!
     welcome to index page..... brace
     wrapper args:
     wrapper kwargs:
     waiting for development......!
     welcome to index page.....
  • 相关阅读:
    如何实现CSS限制字数,超出部份显示省略号
    html禁止手机页面放大缩小
    jQuery 获取屏幕高度、宽度
    谷歌api 二维码生成 实例
    java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA
    eclipse安装阿里开发规范
    tomcat下配置http和https
    linux安装redis
    修改java配置文件
    Linux下安装Mysql
  • 原文地址:https://www.cnblogs.com/brace2011/p/9194064.html
Copyright © 2011-2022 走看看