zoukankan      html  css  js  c++  java
  • 装饰器补充

    一、通用装饰器回顾

    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                     第三层装饰器后

  • 相关阅读:
    mysql group_concat函数
    easyui textbox获取焦点事件
    jquery获取select下拉框的前一个,后一个,第一个,最后一个option对象
    easyui 只刷新当前页面的数据 datagrid reload 方法
    spring-data-jpa查询语句的书写实例小计
    jquery给input标签添加data-options属性
    正则表达式的常用方法
    正则表达式之 /^(d)$/
    jquery获取下拉列表的值和显示内容的方法
    一个 关于 case when的SQL
  • 原文地址:https://www.cnblogs.com/molieren/p/9188004.html
Copyright © 2011-2022 走看看