• 装饰器


    定义:

      器字代表函数,装饰器本质是函数;装饰:装饰其他函数,就是为其他函数添加附加功能

    原则:

      1.不能修改被装饰函数的源代码(在不修改被装饰函数源代码的情况下为其添加功能)

      2.不能修改被装饰的函数的调用函数,被装饰函数不知道被装饰了

    实现装饰器需要了解:

      1.函数及变量:内存存储函数方式与存储变量一样:内存中存储函数体,再指向函数名

      2.高阶函数

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

    b.返回值中包含函数名(不修改函数的调用方式)

     1 import time
     2 def bar():#bar是这个函数的门牌号
     3     time.sleep(2)
     4     print('in the bar')
     5 def test1(func):#不是装饰器,是因为函数的调用方式test1(bar)被更改了
     6     start_time=time.time()
     7     func()
     8     stop_time=time.time()
     9     print('the func fun time is %s' % (stop_time-start_time))
    10 
    11 test1(bar) #func=bar

     运行结果:

      

     1 import time
     2 def bar():#bar是这个函数的门牌号
     3     time.sleep(2)
     4     print('in the bar')
     5 
     6 def test2(func):
     7     print(func)
     8     return func
     9 
    10 print(test2(bar))
    11 print('--------------------')
    12 bar=test2(bar)
    13 print('--------------------')
    14 bar()

    运行结果:

      3.嵌套函数:在已定义的函数内部再定义函数

    1 def foo():
    2     print('in the foo')
    3     def bar():#bar具有局部变量的特性
    4         print('in the bar')

    通过高阶函数和嵌套函数实现装饰器功能:

     1 import time
     2 
     3 def timer(func):#在被装饰函数之外嵌套装饰器函数,添加装饰功能
     4     def deco(*args,**kwargs):#不固定参数参数
     5         start_time=time.time()
     6         result=func(*args,**kwargs)#被装饰的函数在这运行
     7         stop_time=time.time()
     8         print('the func run time is %s' % (stop_time-start_time))
     9 
    10         return result#加入了返回值
    11     return deco#timer这个函数返回了deco函数的地址
    12 
    13 @timer#@timer等于test1=timer(test1):返回了deco函数的内存地址赋给了test1,此时test1是新的test1,这时的test1已经有了装饰器的功能
    14 def test1():
    15     time.sleep(3)
    16     print('in the test1')
    17 
    18 @timer#test2=timer(test2),deco=test2
    19 def test2(name):
    20     time.sleep(3)
    21     print('test2:',name)
    22     print('in the test2')
    23     return 'from test2'#加入了返回,装饰器内的函数也要加返回
    24 
    25 test1()
    26 print('-----------------')
    27 print(test2('tao'))#print打印函数的返回值

    运行结果:

      所以说,装饰器就是将被装饰函数在装饰器函数内执行,再将装饰器函数赋予被装饰函数名,之后再执行被装饰函数时就相当于执行了装饰器函数,即在没有改变被装饰函数的源代码和调用方式的情况下,实现了装饰的功能。

    实现加入参数的装饰器:

     1 user,passwd='Tao','abc'
     2 def auth(auth_type):#与未加参数的装饰器区别:装饰器多加了一个参数,要多嵌套一层函数;auth返回的仍是wrapper这个函数
     3     def outer_wrapper(func):#注意加入的参数和func的位置
     4         def wrapper(*args, **kwargs):#auth函数返回out_wrapper,out_wrapper函数返回wrapper,所以auth函数返回的仍是wrapper这个函数
     5 
     6             #判断参数
     7             if auth_type=='local':
     8                 username = input('username:').strip()
     9                 password = input('passwd:').strip()
    10 
    11                 if user == username and passwd == password:
    12                     print('欢迎')
    13                     res = func(*args, **kwargs)  #当被装饰函数有返回值时
    14                     return res
    15                 else:
    16                     exit('错误')
    17 
    18             #判断参数
    19             elif auth_type=='ldap':
    20                 print('ldap无法实现')
    21 
    22         return wrapper
    23 
    24     return outer_wrapper
    25 
    26 
    27 
    28 def index():
    29     print('welcome to index page')
    30 
    31 @auth(auth_type='local')#auth返回了wrapper这个函数赋给了home
    32 def home():
    33     print('welcome to home page')
    34     return "from home" #加入了返回,装饰器内的函数也要加返回
    35 
    36 @auth(auth_type='ldap')#auth返回了wrapper这个函数赋给了bbs
    37 def bbs():
    38     print('welcome to bbs page')
    39 
    40 index()
    41 print('--------------------')
    42 print(home())#打印函数的返回值即from home
    43 print('--------------------')
    44 bbs()

    运行结果:

  • 相关阅读:
    ActiveReports 报表应用教程 (3)---图表报表
    ActiveReports 报表应用教程 (4)---分栏报表
    ActiveReports 报表应用教程 (5)---解密电子商务领域首张电子发票的诞生(套打报表)
    hdu4467 Graph
    ActiveReports 报表应用教程 (6)---分组报表
    [leetcode]Search a 2D Matrix
    参加百度开放云编程马拉松后一点总结
    CAS服务器配置
    Tomcat 的 SSL 配置
    在windows server 2008 R2 64bit上面配置PI OPC Server的DCOM
  • 原文地址:https://www.cnblogs.com/BIT-taozhen/p/9800324.html
Copyright © 2020-2023  润新知