装饰器

函数的开放封闭原则:  对扩展是开放的 对修改是封闭的

装饰器的主要功能:

  在不改变函数调用方式的基础上在函数的前、后添加功能。

装饰器的本质:一个闭包函数

装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

装饰器的本质是闭包函数,它与外部函数建立连接的参数是主函数名,也就是说,主函数名被装饰器外层函数当作参数传递给了内层函数去运行.

装饰器的基本结构:

 1 ===========================#装饰器的基本形态=============================
 2 def 装饰器名 ( 被装饰主函数名 ):
 3     def 内层函数名 ( 被装饰主函数参数 ):
 4         先执行 被装饰主函数还未执行 前 添加的操作     #装饰器操作      
 5         V = 被装饰主函数名()
 6         再执行  被装饰主函数执行结束 后 添加的动作     #装饰器操作
 7         return V  #(被装饰函数的返回值)(可有可无)
 8     return 内层函数名       #这里是装饰器函数的返回值,return 的是内层函数地址
 9 @装饰器名    <=====>  被装饰主函数名 = 装饰器名 (被装饰主函数名) 
10              # 实质上是被装饰主函数名 = 装饰器函数的返回值,也就是内层函数名
11 def 被装饰函数名 ( 被装饰函数参数 ):   #这里调用主函数,因为装饰器而等于调用内层函数
12      被装饰函数,也就是主体函数的函数体
13       return 主体函数的返回值 #(可有可无)
14=========================================================================
 #=====================装饰器基本形态=========================
1
def wrapper ( func ): 2 def inner ( *args **kwargs ): 3 print('函数执行前添加的动作') 4 'V' = func( *args **kwargs ) 5 print('函数执行后添加的动作') 6 return V 7 return inner 8 @wrapper #func = wrapper ( func )--返回值-->inner 9 def func ( *args **kwargs ): 10 print('这是主函数体') 11 return V
===========================================================

在函数使用装饰器后,查看注释信息方法不能用,这是需要使用functool模块的wraps功能

 1 from functools import wraps
 2 
 3 def deco(func):
 4     @wraps(func) #加在最内层函数正上方
 5     def wrapper(*args,**kwargs):
 6         return func(*args,**kwargs)
 7     return wrapper
 8 
 9 @deco
10 def index():
11     '''哈哈哈哈'''
12     print('from index')
13 
14 print(index.__doc__)    #查看函数注释
15 print(index.__name__)   #查看函数名
16 
17 装饰器——wraps demo

 语法糖@主要作两件事:

  1.执行外部装饰器函数wrapper,并把被装饰函数func当作参数传递给装饰器wrapper(func)

   2.把装饰器函数的返回值赋值给被装饰函数 func = wrapper (func)返回值=inner#内部函数

装饰器的用法: 在被装饰函数的上面加语法糖@装饰器名,再上面创建 装饰器名(被装饰函数) 函数,再建立 内层函

数(携带被装饰函数参数) ,在内层函数函数体中执行被装饰函数前后加新功能,正常输出,给外层装饰器返回值为内层函数.

带参数的装饰器

  • 作用:带参数的装饰器可以通过最外层参数传递到内层来约束内层函数执行次数.条件等等

示例一    返回每次结果列表
def outer(a):
    def wrapper(func):
        def inner(*args,**kwargs):
            # v=[]        #添加列表
            for i in range(a):
                z=func(*args,**kwargs)
                # v.append(z)  #添加列表
                print(z)    #不添加,每次执行显示结果
            # return v
        return inner
    return wrapper
@outer(5)
def func(q):
    return q+1
print(func(1))
#注意:每次输出返回值,最后一次返回inner的返回值none 
示例二   比较返回最大值,for循环参数限制执行次数
def outer(a):
    def wrapper(func):
        def inner(*args,**kwargs):
            v=0
            for i in range(a):
                z=func(*args,**kwargs)
                if z>v:
                    v=z
                print(z)
            return z
        return inner
    return wrapper
@outer(5)
def func(i):
    return 8
print(func(1))
示例三     分情况决定是否执行装饰函数 True False
def outer(a):
    def wrapper(func):
        def inner(*args,**kwargs):
            if a:
                z=func(*args,**kwargs)
                return z
            else:
                z = func2(*args, **kwargs)
                return z
        return inner
    return wrapper
@outer(True)
def func(i):
    print('第一种情况下执行')
print(func(1))
@outer(False)
def func2(i):
    print('第二种情况下')
print(func(2))
原文地址:https://www.cnblogs.com/OB19227/p/10711067.html