1、关于函数的装饰器
 
开闭原则:
    对功能的扩展
    对代码的修改是封闭
 
通用装饰器语法(python里面的动态代理)
存在的意义:在不破坏原有函数和原有函数调用的基础上,给函数添加新的功能
def wrapper(fn):    # fn是目标函数
    def inner(*args, **kwargs):  # 聚合   为目标函数传参,无敌传参,接收到的是元组
        # 在执行目标函数之前
        ret = fn(*args, **kwargs) # 接收到的所有参数,打散传递给正常参数, 调用目标函数,ret是目标函数的返回值
        # 在执行目标函数之后
        return ret  # 把目标函数返回值返回,保证函数正常运行
    return inner

@wrapper  # target_func = wrapper(target_func)  # 此时fn就是target_func
def target_func():
    pass

target_func()  # 此时执行的是inner()

2、带有参数的装饰器 

def wrapper_out(flag): # 装饰器本身的参数
    def wrapper(fn): # 目标函数
        def inner(*args, **kwargs): # 目标函数执行需要的参数
            if flag == True:
                print('看看天气预报,知道明天天气怎么样')
                ret = fn(*args,**kwargs) # 在执行目标函数之前
                print('下雨了,天气预报不太准啊')
                return ret
            else:
                ret = fn(*args,**kwargs) # 在执行目标函数之前
                return ret
        return inner
    return wrapper

#语法糖 @装饰器
@wrapper_out(True) # 先执行wrapper_out(True),返回一个装饰器,再和@拼接 @装饰器
def pashan(): #被wrapper装饰
    print('去爬山了')

pashan()

3、多个装饰器装饰同一个函数 

def wrapper1(fn):
    def inner(*args,**kwargs):
        print(1111)
        ret = fn(*args, **kwargs)
        print(2222)
        return ret
    return inner

def wrapper2(fn):
    def inner(*args, **kwargs):
        print(3333)
        ret = fn(*args, *kwargs)
        print(4444)
        return ret
    return inner


# 就近原则
@wrapper1
@wrapper2

def func():
    print('今天你在做什么')

func()

'''
1111
3333
今天你在做什么
4444
2222
'''

执行顺序:首先@wrapper1装饰起来,然后获取到一个新函数是wrapper1中的inner,然后执行@wrapper2,这个时候,@wrapper2装饰的就是@wrapper1中的inner了,所以执行顺序就像:第二层装饰器前(第一层装饰器前(目标)第一层装饰器后)第二层装饰器后,程序从左到右执行起来 

posted on 2018-12-14 20:52  古鲁月  阅读(136)  评论(0编辑  收藏  举报