zoukankan      html  css  js  c++  java
  • 装饰器

    最近在学习Python,到装饰器这一部分,不知理解的是否正确

      1 #coding:utf-8
      2 
      3 #装饰器原理介绍和基本实现
      4 
      5 #例子
      6 '''
      7 说明:
      8 1.假设在调用home()和move()函数前,需要先验证
      9 2.但是不能修改home()和move()里面的代码
     10 
     11 方法步骤:
     12 1.设定一个新的验证函数login(),让home()和move()函数执行前,先执行login()函数
     13 2.给login()方法传参,参数为tv函数的内存地址(tv函数不带"()",这样传入的就是内存地址而不会执行函数)
     14 3.login()函数设定返回值,返回值为tv函数传入的内存地址(也就是tv)
     15 4.用一个变量来接收login()函数返回的值(返回值为tv函数的内存地址)
     16 5.接收login()函数的变量tv,加上括号"tv()",执行tv()函数
     17 '''
     18 



     19 #用普通函数来实现以上要求
     20 def login(func):    #验证函数
     21     print("passed user verification...")
     22     print(func)
     23     return func
     24 
     25 def tv(name):       #tv函数
     26     print("Welcome 【%s】 to tv page"%name)
     27 
     28 tv = login(tv)      #login()函数传入tv()函数的内存地址(tv函数并不执行),在用一个变量tv来接收返回值
     29 tv("eric")          #此时tv变量值为tv()这个函数的内存地址,加上“()”来执行此函数
     30 
     31 



    32 #用装饰器来实现以上要求 33 def login(func): 34 print("passed user verification...") 35 print(func) 36 return func #返回tv函数的内存地址 37 38 @login #@login == login(tv)#1.程序开始加载时,就会先执行login()函数,并把tv函数的内存地址做为参数传入login()函数 39 def tv(name): 40 print("Welcome 【%s】 to tv page"%name) 41 42 tv("eric") #2.调用tv函数,此时执行tv()函数 43 44



    45 #上面的例子有一个问题,当程序执行到@login装饰器时会马上执行里面的方法,我们不希望这样,而是希望调用tv函数时才执行里面的方法 46 def login(func): #2.把login()函数载入内存中 47 def inner(arg): #4.arg == eric"; 48 print("passed user verification...") 49 func(arg) #5.func == tv函数的内存地址;加上"(arg)"就是调用tv()函数并传入参数"arg" 50 return inner 51 52 @login #1.程序开始加载时先执行login()函数,并把tv函数的内存地址做为参数传入login()函数 53 def tv(name): 54 print("Welcome 【%s】 to tv page"%name) 55 return 111 56 #tv = login(tv) 57 tv("eric") #3.这个tv是一个变量,值为login()函数的返回值,目前返回值为inner函数的内存地址,通过执行tv("eric")传入参数,相等于调用了inner("eric") 58



    59 60 #函数调用时传多个参数 61 def login(func): 62 def inner(*args,**kwargs): #调用时多参数传参 63 print("passed user verification...") 64 func(*args,*kwargs) 65 return inner 66 67 @login 68 def tv(name,passwd=123): 69 print("Welcome 【%s】 to tv page your password is 【%s】"%(name,passwd)) 70 return 111 71 #tv = login(tv) 72 tv("eric",'123456') 73 74 75

     76 
     77 ##实现带参数的装饰器
     78 '''
     79 要求:
     80 用一个可带参数的装饰器实现功能复用
     81 1.再某个函数执行时(例如index()函数),需要在函数的前面和后面分别执行一个其它函数
     82 2.假如有N个类似index(),需要怎么实现
     83 '''
     84 106 #执行顺序
    #1、执行Filter(before,after)     #装饰器有参数(不会再把它下面的函数当做参数传入)
    #2、outer                        #在装饰器嵌套的第二层outer函数,才会把Index内存对象函数当做参数传入
    #3、Index = 新的Index            #装饰器会返回一个函数内存对象,让装饰器下面的函数接收(Index()函数)
    #4、Index("aa","bb")             #接收装饰器返回的内存对象后,调用执行

    85 def Before(request, kargs): 86 print('before') 87 88 def After(request, kargs): 89 print('after') 90 91 def Filter(before_func, after_func): 92 def outer(main_func): #2.在执行outer装饰器,传入Index函数的内存对象,并返回warpper函数的内存对象给Index变量 93 def wrapper(request, kargs): #4.request == "aa", kargs == "bb" 94 before_func(request, kargs) #5.before_func为Before函数的内存对象,调用并传参("aa","bb") 95 main_func(request, kargs) #6.main_func为Index函数的内存对象,调用并传参("aa","bb") 96 after_func(request, kargs) #7.after_func为After函数的内存对象,调用并传参("aa","bb") 97 return wrapper 98 return outer 99 100 @Filter(Before, After) #1.执行Filter装饰器(参数为Before, After两个函数内存对象),有参数的Filter装饰器不会再把Index的内存对象传入 101 def Index(request, kargs): 102 print('index') 103 104 Index("aa","bb") #3.Index变量接收warpper函数的内存对象,调用arpper函数并传参"("aa","bb")"

     例子:

     1 ##带参数的装饰器
     2 '''
     3 说明:
     4 1.假设在调用home()和move()函数前,需要先验证
     5 2.但是不能修改home()和move()里面的代码
     6 
     7 方法步骤:
     8 1.设定一个新的验证函数login(),让home()和move()函数执行前,先执行login()函数
     9 2.给login()方法传参,参数为tv函数的内存地址(tv函数不带"()",这样传入的就是内存地址而不会执行函数)
    10 3.login()函数设定返回值,返回值为tv函数传入的内存地址(也就是tv)
    11 4.用一个变量来接收login()函数返回的值(返回值为tv函数的内存地址)
    12 5.接收login()函数的变量tv,加上括号"tv()",执行tv()函数
    13 '''
    14 
    15 
    16 def Before(request, kargs):
    17     print('before')
    18 
    19 def After(request, kargs):
    20     print('after')
    21 
    22 def Filter(before_func, after_func):
    23     def outer(main_func):
    24         def wrapper(request, kargs):
    25             before_func(request, kargs)
    26             main_func(request, kargs)
    27             after_func(request, kargs)
    28         return wrapper
    29     return outer
    30 
    31 @Filter(Before, After)
    32 def Index(request, kargs):
    33     print('index')
    34 
    35 Index("aa","bb")
    View Code
  • 相关阅读:
    2012619 win7环境Jooma建站手记解决问题
    linux学习(4)ubuntu开机自动挂载nfs服务器上的home分区
    linux学习(3)nginx tomcat集群
    oracle to_date 函数
    inux学习(2)vim设置
    linux学习(1)常用命令入门
    tomcat域名绑定
    tomcat内存溢出问题解决思路
    TreeView控件无限级 一次性加载和异步加载剖析
    数据查询支持中文拼音首字母模糊检索
  • 原文地址:https://www.cnblogs.com/l729414559/p/6843435.html
Copyright © 2011-2022 走看看