博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
day6 装饰器总结
阅读量:6258 次
发布时间:2019-06-22

本文共 8316 字,大约阅读时间需要 27 分钟。

 装饰器:开放封闭原则,为一个函数加上新的功能,不改变原函数,不改变调用方式

def fun2(wtf):     def fun3():         print('i am pythoner!!! ')         wtf()     return fun3 @fun2 def fun1():     print('this is fun1') fun1() 输出:

i am pythoner!!!

this is fun1

 

 

 

1 def fun2(wtf): 2     def fun3(*args, **kwargs): 3         print('i am pythoner!!! ') 4         wtf(*args, **kwargs) 5     return fun3     #这里不是fun3()是因为:return作用在于函数赋值,即让fun3指向fun1的函数内存地址 6          7 @fun2     # @fun2  当于fun1 = fun2(fun1) ,把下面的函数传递到装饰器函数里面,相当于 fun1 = fun2(fun1) = fun3(用return令fun1=fun3), 后面再执行fun1() , 相当于执行fun3() 8 def fun1(arg, arg2): 9     print('this is fun1: %s %d' % (arg, arg2))10 fun1('tom', 55)                      #注意此处fun1()调用的实际是fun3(),而不是原来的fun1()了   注意:只要函数应用装饰器,函数就被重新定义,重新定义为:装饰器的内层函数

 

def runtime(func):     def warpper():         start_time = time.time()         func()         end_time = time.time()         print 'run time is %s' % (end_time-start_time)     return warpper @runtime def test1():     time.sleep(3)     print 'in the test1' test1() 带参数的装饰器举例:
1 def outer(func): 2     def inner(a, b): 3         print('heihei') 4         r = func(a, b)    #func即index函数,即inner函数 5         return r 6     return inner 7  8  9 @outer                 # index = outer(index) = inner10 def index(a1, a2):11     print('----------')12     return a1 + a213 14 print(index(1, 2))15 16  输出:17 heihei18 ---------- 19 3 @outer 作用 1. 执行outer函数,将index作为参数传递 2. 将outer的返回值,重新赋值给index 3. 执行index函数时不再是原来的index函数,而是执行装饰器中的inner函数(由装饰器中的return赋值使index=inner)

 

带N个参数的装饰器: 应用场景: 当一个装饰器装饰多个函数时,而这些函数的参数个数都不相同时。 原理:
1 #原理: 2 def f1(*args, **kwargs): 3     print(args) 4     print(kwargs) 5  6 f1(1, 2, 3, 4, M1='123') 7 输出: 8 (1, 2, 3, 4) 9 {
'M1': '123'}10 11 dic = {
'a': 2, 'b': 23333}12 tup = (1, 2, 3)13 f1(*tup, **dic)14 15 输出:16 (1, 2, 3)17 {
'a': 2, 'b': 23333}
View Code
举例:
1 def outer(func): 2     def inner(*args, **kwargs): 3         print('into inner') 4         print('the arg is :', *args, **kwargs) 5         r = func(*args, **kwargs) 6         return r 7     return inner 8  9 @outer                 # index = outer(index) = inner10 def index(a1, a2):11     print('----------')12     return a1 + a213 14 print(index(1, 2))15 16 @outer                  # f1 = outer(f1) = inner17 def f1(a1):18     print('++++++++++++++++++++++++++')19     return a1 * a120 print(f1(2))21 22 #输出:23 into inner24 the arg is : 1 225 ----------26 327 into inner28 the arg is : 229 ++++++++++++++++++++++++++30 4

 

多个装饰器装饰同一个函数:
1 def outer(func):                 #func等同于outer2中的inner2 2     def inner(*args, **kwargs): 3         print('first decorate-------------') 4         print('the arg is :', *args, **kwargs) 5         r = func(*args, **kwargs)       #func等于outer2中的inner2,r值为inner2中的 return r 6         print('first decorate-------------') 7         return r                 # r的值最终返回给index 8     return inner 9 10 11 def outer2(func):                 #func等于index12     def inner2(*args, **kwargs):       #inner2等同于于outer2+被outer2装饰的index函数13         print('second decorate-----------')14         r = func(*args, **kwargs)       #func等于index,r值为index的return a1 + a215         print('second decorate------------')16         return r                 #r为inner2的返回值,返回给outer中的func函数17     return inner218 19 20 @outer         #      outer(inner2) = inner, 作用:将outer2装饰的index,即inner2当作参数传递到第一个装饰器中outer中21 @outer2     # index = outer2(index) = inner2  22 def index(a1, a2):23     print('ori func----------')24     return a1 + a225 26 print(index(1, 2))27 28 输出:29 first decorate-------------30 the arg is : 1 231 second decorate-----------32 ori func----------33 second decorate------------34 first decorate-------------35 3 执行顺序说明: 当运行index(1, 2)时, 1.执行第一个装饰器outer中的inner函数 2.由1步中的inner函数中的func函数,执行outer2中的inner2函数 3.执行outer2中inner2中的func函数,即执行最初需要装饰的index函数 4.index的返回值返回给它的调用者,即inner2中的func函数 5。inner2的返回值返回给它的调用者,即inner中的func函数 6.将r返回给index函数

 

 

自身带参数的装饰器

 例1:

1 user_list=[ 2     {
'name':'alex','passwd':'123'}, 3 {
'name':'linhaifeng','passwd':'123'}, 4 {
'name':'wupeiqi','passwd':'123'}, 5 {
'name':'yuanhao','passwd':'123'}, 6 ] 7 current_dic={
'username':None,'login':False} 8 9 def auth(auth_type='filedb'):10 def auth_func(func):11 def wrapper(*args,**kwargs):12 print('认证类型是',auth_type)13 if auth_type == 'filedb':14 if current_dic['username'] and current_dic['login']:15 res = func(*args, **kwargs)16 return res17 username=input('用户名:').strip()18 passwd=input('密码:').strip()19 for user_dic in user_list:20 if username == user_dic['name'] and passwd == user_dic['passwd']:21 current_dic['username']=username22 current_dic['login']=True23 res = func(*args, **kwargs)24 return res25 else:26 print('用户名或者密码错误')27 elif auth_type == 'ldap':28 print('鬼才特么会玩')29 res = func(*args, **kwargs)30 return res31 else:32 print('鬼才知道你用的什么认证方式')33 res = func(*args, **kwargs)34 return res35 36 return wrapper37 return auth_func38 39 @auth(auth_type='filedb') #auth_func=auth(auth_type='filedb')-->@auth_func 附加了一个auth_type --->index=auth_func(index)40 def index():41 print('欢迎来到京东主页')42 43 @auth(auth_type='ldap')44 def home(name):45 print('欢迎回家%s' %name)46 #47 @auth(auth_type='sssssss')48 def shopping_car(name):49 print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))50 51 # print('before-->',current_dic)52 # index()53 # print('after--->',current_dic)54 # home('产品经理')55 shopping_car('产品经理')

 

 例2:

1 # !/usr/bin/env python 2 # coding:utf-8 3  4  5 def before(request, kargs): 6     print('before') 7  8  9 def after(request, kargs):10     print('after')11 12 13 def Filter(before_func, after_func):14     def outer(main_func):15         def wrapper(request, kargs):16 17             before_result = before_func(request, kargs)18             if before_result:19                 return before_result20 21             main_result = main_func(request, kargs)22             if main_result:23                 return main_result24 25             after_result = after_func(request, kargs)26             if after_result:27                 return after_result28 29         return wrapper30 31     return outer32 33 # outer = Filter(before, after) ---> 相当于@outer附带参数(before, after) 相当于执行 ==> index = outer(index)34 @Filter(before, after)35 def index(request, kargs):36     print('index')37 38 index(1,2)39 40 41 # 带参数的装饰器:利用装饰器的最外层函数传参

 

 

 

 

 

 

装饰器------------自己的理解(持续更新)

1 def fun2(wtf): 2     def fun3(): 3         print('i am pythoner!!! ') 4         wtf() 5     return fun3 6  7  8 @fun2 9 def fun1():10     print('this is fun1')11 fun1()12 13 输出:14 i am pythoner!!! 15 this is fun116 17 18 19 fun2只是个桥梁:20 0.把要装饰的函数接收进来,嵌套进包含新功能的函数(这个函数同时包含原函数功能)21 1.让fun1和fun3内存地址相同22 23 24 目的:装饰后在fun1()执行前后再执行一些其他的动作25 26 27 28 def outer(func):                                                                          #29     def inner(a, b):                                                                      # 2  a:1 b:230         print('heihei')                                                                   # 331         r = func(a, b)    # func即index函数,即inner函数                                  # 432         return r         # 如果index有返回值,这里要加上return返回index的返回值        # 733     return inner         # 作用:让index和inner内存地址相同34 35 36 @outer                 # index = outer(index) = inner37 def index(a1, a2):38     print('----------')                                                                    # 539     return a1 + a2                                                                         # 640 41 42 print(index(1, 2))             # 偷梁换柱,相当于直接执行包含原函数功能的函数inner(1, 2)             # 1

 

 

def write_log(func):    def wrapper(a, b):        print 'log --------------'        return func(a, b)    return wrapper# @write_logdef bar(a,b):    return a + bprint write_log(bar)(1, 3)#  write_log(bar)        等于 wrapper#  write_log(bar)(1, 3)  等于 wrapper(1, 3)#输出:log --------------4

 

转载于:https://www.cnblogs.com/yum777/p/6771403.html

你可能感兴趣的文章
使用RNA-seq数据通过网络熵评估肿瘤内异质性
查看>>
Scrapy基础——Spider
查看>>
Airbnb 宣布放弃使用 React Native,回归使用原生技术
查看>>
PyCharm for Mac快捷键小记
查看>>
Html5的从0到1-Html5的web Storage概述(16)
查看>>
中国IT行业盛行,程序员“过多”是主要原因?
查看>>
史上最难的一道Java面试题:分析篇
查看>>
HDFS常用命令(方便大家记忆版)
查看>>
kafka原理与实践(原创)
查看>>
如何在excel单元格中插入图片批注
查看>>
Android 基础动画之补间动画详解
查看>>
业界 | 全球最大生物识别数据库被判定合法
查看>>
Hanlp等七种优秀的开源中文分词库推荐
查看>>
常见移动设备的 CSS3 Media Query 整理(iPhone/iPad/Galaxy/HTC One etc.)
查看>>
redis第二步(事务和锁)
查看>>
rufus:一款制作linux U盘启动的神器
查看>>
[动态代理三部曲:中] - 从动态代理,看Class文件结构定义
查看>>
函数式编程与面向对象编程[5]:编程的本质
查看>>
[Spring实战系列](9)装配集合
查看>>
vue需注意的地方
查看>>