zoukankan      html  css  js  c++  java
  • 净心诀---python3装饰器

    python3装饰器

    装饰器作用

    简单理解:可以为已有函数添加额外功能

    例:

    已有2个函数如下

    1 def MyFunc1():
    2     print("This is a print function1")
    3 
    4 
    5 def MyFunc2():
    6     print("This is a print function2")

    需求:现想要在函数执行前打印类似(开始使用XXX功能)

    不用装饰器方式:

    1 def MyFunc1():
    2     print("开始使用MyFunc1功能")
    3     print("This is a print function1")
    4 
    5 
    6 def MyFunc2():
    7     print("开始使用MyFunc2功能")
    8     print("This is a print function2")

    调用函数时输出:

    思考:如果有很多很多的函数,那么每个函数中都要修改(而且这需要在已有函数内部去修改,部分情况下是不允许修改已有函数的),这个方式显然不可靠

    采取装饰器的方式做

    装饰器模板(写法)

    1 def ShowFunction(func):
    2     def inner(*args, **kwargs):
    3         # 这里写函数执行前的功能
    4         ret = func(*args, **kwargs)
    5         return ret        
    6     return inner

    利用上述装饰器模板,来写一个上述需求的装饰器

     1 # 这是一个装饰器
     2 def ShowFunction(func):
     3     def inner(*args, **kwargs):
     4         name = func.__name__
     5         print("开始使用%s功能" %name)
     6         ret = func(*args, **kwargs)
     7         return ret        
     8     return inner
     9 
    10 
    11 @ShowFunction    # @加函数名  这种形式就是使用某个装饰器的写法
    12 def MyFunc1():
    13     print("This is a print function1")
    14 
    15 @ShowFunction
    16 def MyFunc2():
    17     print("This is a print function2")
    18 
    19 
    20 MyFunc1()
    21 MyFunc2()

    效果如下:

     现在基本上就能满足上述需求

    思考:有时候不是所有的装饰器都是永久装饰函数的,在某些情况下我们会希望装饰器不生效,此时需要用到带有参数的装饰器

    此时我们一般会在装饰器外部在套一个函数,来接受一个Flag,在内部用这个Flag来判断是否生效装饰器

     1 # 现需要在调用每个函数前说明这是哪个函数,用到带装饰装饰器(可控制是否使装饰器生效)
     2 from functools import wraps
     3 
     4 # 这是一个装饰器
     5 Flag = 1
     6 def FuncWrap(Flag):
     7     def ShowFunction(func):
     8         @wraps(func)    #使外部函数调用函数属性时,不被装饰器影响
     9         def inner(*args, **kwargs):
    10             if Flag:
    11                 name = func.__name__
    12                 print("开始使用%s功能" %(name))
    13                 ret = func(*args, **kwargs)
    14             else:
    15                 ret = func(*args, **kwargs)    
    16             return ret        
    17         return inner        
    18     return ShowFunction
    19 
    20 
    21 
    22 @FuncWrap(Flag)    # 等于写法-->MyFunc1 = ShowFunction(MyFunc1)
    23 def MyFunc1():
    24     print("This is a print function1")
    25 
    26 @FuncWrap(Flag)
    27 def MyFunc2():
    28     print("This is a print function2")
    29 
    30 # print(MyFunc1.__name__)
    31 MyFunc1()
    32 MyFunc2()

    我们可以修改Flag的值1(生效)或0(不生效)

    扩展:多个装饰器共同装饰一个函数

     1 # 这是一个装饰器1
     2 def Wrap1(func):
     3     def inner(*args, **kwargs):
     4         print("start装饰器1")
     5         ret = func(*args, **kwargs)
     6         print("end装饰器1")
     7         return ret        
     8     return inner
     9 
    10 # 这是一个装饰器2
    11 def Wrap2(func):
    12     def inner(*args, **kwargs):
    13         print("start装饰器2")
    14         ret = func(*args, **kwargs)
    15         print("end装饰器2")
    16         return ret        
    17     return inner
    18 
    19 @Wrap1
    20 @Wrap2
    21 def MyFunc1():
    22     print("This is a print function1")
    23 
    24 MyFunc1()

    关于多装饰器现象(记住即可):

  • 相关阅读:
    将深度学习低延迟推理性能提高一倍
    常量特征
    数据库链接笔记
    html5页面调用手机打电话功能
    插件使用一表单验证一validation
    插件使用一树形插件---zTree一zTree异步加载
    插件使用一树形插件---zTree
    插件使用一进度条---nprogress
    插件使用一颜色选择器---cxColor
    插件使用一顶部消息提示---overhang
  • 原文地址:https://www.cnblogs.com/zakker/p/12047878.html
Copyright © 2011-2022 走看看