python装饰器详述

Posted 仙寓游子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.....







































































































































































































































































































































以上是关于python装饰器详述的主要内容,如果未能解决你的问题,请参考以下文章

Python 装饰器和装饰器模式有啥区别?

python 装饰器:装饰器实例内置装饰器

python 装饰器:装饰器实例内置装饰器

python 装饰器:装饰器实例类装饰器(装饰函数)

python 装饰器:装饰器实例类装饰器(装饰函数)

理解Python装饰器