zoukankan      html  css  js  c++  java
  • python开发函数进阶:装饰器

    一,装饰器本质

    闭包函数

    功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能

    作用:解耦,尽量的让代码分离,小功能之前的分离。

       解耦目的,提高代码的重用性

    二,设计模式

    开放封闭原则

    *对扩展是开放的

    *对修改是封闭的

    三,代码解释

    *通用代码

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 
     4 def timmer(func):  #---> jjj
     5     def inner(*args,**kwargs):
     6         ret = func(*args,**kwargs)  # --->ret = jjj()
     7         # print('没有返回值的调用')
     8         return ret
     9     return inner
    10 
    11 @timmer #jjj = timmer(jjj)  语法糖
    12 def jjj():
    13     return 123
    14 # jjj()    #调用函数,如果被装饰的函数有返回值,就需要下边的代码
    15 ret = jjj()  #==>inner    有返回值
    16 print(ret)  #返回123

    执行顺序

     

    *用装饰器简单实现用户登录,登陆一个函数成功,无需再次登陆

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 
     4 tag = False
     5 
     6 def login(func):
     7     def inner(*args,**kwargs):
     8         global tag
     9         if tag == False:
    10             user = input('please your username>>>:')
    11             pwd = input('please your password>>>:')
    12             f = open('aaa','r',encoding='utf-8')
    13             for i in f:
    14                 user_pwd = eval(i)
    15                 if user == user_pwd['name'] and pwd == user_pwd['password']:
    16                     tag = True
    17             f.close()
    18         if tag:
    19             ret = func(*args,**kwargs)
    20             return ret
    21     return inner
    22 
    23 @login
    24 def haha(*args,**kwargs):
    25     print('中国动漫')
    26     pass
    27 
    28 @login
    29 def hengheng(*args,**kwargs):
    30     print('美国动漫')
    31     pass
    32 ##########用户调用方式
    33 haha()
    34 hengheng()

     *统计函数中有多少个函数被装饰了

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 
     4 l = []
     5 def wrapper(func):
     6     #l.append(func)  #统计当前程序中有多少个函数被装饰了
     7     def inner(*args,**kwargs):
     8         l.append(func)  #统计本次程序执行有多少个带这个装饰器的函数被调用了
     9         ret = func(*args,**kwargs)
    10         return ret
    11     return inner
    12 
    13 @wrapper  #f1 = wrapper(f1)
    14 def f1():
    15     print('in f1')
    16 
    17 @wrapper #f2 = wrapper(f2)
    18 def f2():
    19     print('in f2')
    20 
    21 @wrapper #f2 = wrapper(f2)
    22 def f3():
    23     print('in f3')
    24 f1()
    25 f2()
    26 f3()
    27 
    28 print(len(l))

    四,双层带参数的装饰器

    顾名思义,就是给装饰器添加参数

    可以控制被装饰的函数是否需要这个装饰器,或者其他用法

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 
     4 #带参数的装饰器 开关 ,控制是否需要装饰器
     5 
     6 F = False    #通过这里控制是否需要装饰器
     7 def outer(flag):
     8     #以下是装饰器
     9     def wrapper(func):
    10         def inner(*args,**kwargs):
    11             if flag:
    12                 print('before') #被装饰代码运行之前
    13                 ret = func(*args,**kwargs)  #被装饰的代码
    14                 print('after')   #被装饰代码运行之后
    15             else:
    16                 ret = func(*args, **kwargs)
    17             return ret
    18         return inner
    19     ###########################
    20     return wrapper
    21 
    22 @outer(F)   # F默认是FALSE,那么装饰器没有用上,因为 if false: ret = func(),因为加了括号直接执行,返回了wrapper,后面就是装饰器过程了
    23 def hahaha():
    24     print('hahaha')
    25 
    26 @outer(F)   # F如果是TRUE,就用上了装饰器
    27 def shuangww():
    28     print('shuangwaiwai')
    29 
    30 shuangww()
    31 hahaha()

    执行过程

     

    五,多个装饰器装饰一个函数(非重点)

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 
     4 #多个装饰器装饰一个函数
     5 def qqxing(func):  #func = pipixia_inner
     6     def qqxing_inner(*args,**kwargs):
     7         print('in qqxing:before')
     8         ret = func(*args,**kwargs)  #pipixia_inner
     9         print('in qqxing:after')
    10         return ret
    11     return qqxing_inner
    12 
    13 def pipixia(func):  #dapangxie
    14     def pipixia_inner(*args,**kwargs):
    15         print('in pipixia:before')
    16         ret = func(*args,**kwargs)      #dapangxie
    17         print('in pipixia:after')
    18         return ret
    19     return pipixia_inner
    20 
    21 #qqxing(pipixia_inner)  -->dapangxie = qqxing_inner()
    22 @qqxing    #dapangxie = qqxing(dapangxie)  -->dapangxie = qqxing(pipixia(dapangxie)) -->
    23 @pipixia   #dapangxie = pipixia(dapangxie)
    24 def dapangxie():
    25     print("饿了么")
    26 dapangxie()
    27 
    28 #dapangxie = pipixia(dapangxie)
    29 #dapangxie = qqxing(dapangxie)  -->dapangxie = qqxing(pipixia(dapangxie))
    30                                             #pipixia(dapangxie) == >pipixia_inner
    31                                             #qqxing(pipixia_inner) = qqxing_inner
    32 #dapangxie()  ==> qqxing_inner()
  • 相关阅读:
    下班的时候收到两封Mail
    图解SSIS监视文件夹并自动导入数据
    用SqlDependency类为SQL2005查询提供更改通知
    一句话理解ref object的意义
    开源Mono框架将C#编程带到iPhone、Android和Wii
    div css 图片和文字上下居中对齐
    js 表单验证思路
    jquery 表单验证插件
    PHP开源AJAX框架
    Hello China V1.5 源码下载地址
  • 原文地址:https://www.cnblogs.com/jokerbj/p/7247901.html
Copyright © 2011-2022 走看看