装饰器补充

一、通用装饰器回顾

def wrapper(func):
    def inner(*args,**kwargs):
        '执行目标函数之前要执行的内容'
        ret = func(*args,*kwargs)
        '执行目标函数之后要执行的内容'
        return ret
    return inner
@wrapper           #相当于target_func = wrapper(target_func)   语法糖
def target_func():
    print('我是目标函数')

#调用目标函数
target_func()
执行过程:
  1、程序从上到下,当执行到@wrapper时,把函数作为参数传递给wrapper函数,得到inner函数,重新赋值给target_func(把inner赋值给target_func)
  2、当执行到target_func时,我们实际上执行的是inner函数,inner函数会先执行目标函数之前的代码,然后在执行你的目标函数,执行完目标函数最后执行的是目标函数之后的代码。

二、函数的有用信息

  1、给函数添加注释:说明函数的意义

# def eat(food):
#     """
#     吃函数: 把传递进来的内容吃掉     #函数的注释,就是这个函数是干嘛的
#     :param food: 食物            #参数 food 是什么意思
#     :return: None                #返回什么东西
#     """
#     print("我要吃", food)
# eat("烤肉")

  2、获取函数的相关信息

def eat(food):
    """
    吃函数
    :param food:水果
    :return:
    """
    print('我要吃',food)

eat('西瓜')
print(eat.__doc__)               #获取函数的文档注释     函数名._doc_
print(eat.__name__)        #获取函数名称      函数名._name_

执行结果:
我要吃 西瓜

    吃函数
    :param food:水果
    :return:
    
eat
from functools import wraps            #引入函数模块
def wrapper(fn):
    @wraps(fn)                        # 这个代码的作用. 把inner的__name__ __doc__ 替换成fn的__name__
    def inner(*args, **kwargs):
        print("我是前面")
        ret = fn(*args, **kwargs)
        print("我是后面")
        return ret
    return inner

@wrapper # func = wrapper(func)               #@wrapper 把func的_name_改成了inner,@wraps 把inner的_name_改成了func
def func():
    print("我是func")
func()
print(func.__name__)

三、装饰器传参:

from functools import wraps

def wrapper_out(flag):
    def wrapper(fn):       # fn: 被装饰的函数
        @wraps(fn)
        def inner(*args, **kwargs):     # inner => 最终执行的
            if flag == True:
                print("打电话问问金老板.安全不安全啊")
                ret = fn(*args, **kwargs)      # fn 被装饰的函数
                print("金老板骗我")
                return ret
            else:
                ret = fn(*args, **kwargs)     # if 条件不成立,走else
                return ret
        return inner
    return wrapper

                      #传递True和False来控制装饰器内部的运行结果
@wrapper_out(True)    # 带参数的装饰器的执行流程: 先执行@后面的函数. 然后再加上@ 组装成语法糖
def yue():  # inner
    print("约一约")
yue()

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

  

def wrapper(func):
    def inner(*args,**kwargs):
        print('0')
        ret = func(*args,**kwargs)
        print('00')
        return ret
    return inner

def wrapper1(func):
    def inner(*args,**kwargs):
        print('1')
        ret = func(*args,**kwargs)
        print('11')
        return ret
    return inner

def wrapper2(func):
    def inner(*args,**kwargs):
        print('2')
        ret = func(*args,**kwargs)
        print('22')
        print('222')
        return ret
    return inner

@wrapper1          打印顺序:按装饰器顺序从上往下(执行目标函数前),执行目标函数 ,在从下往上(执行目标函数后)
@wrapper2
@wrapper

def target_func():
    print('我是熊猫')

target_func()


执行结果:

1                      第三层装饰器前
2                      第二层装饰器前
0                      第一层装饰器前
我是熊猫    
00                     第一层装饰器后
22                     第二层装饰器后
222                   第二层装饰器后
11                     第三层装饰器后

 

posted @ 2018-06-15 16:42  小小猎魔人  阅读(143)  评论(0编辑  收藏  举报