zoukankan      html  css  js  c++  java
  • python 带参数的装饰器 多个装饰器同时装饰同一个函数

    函数有用的信息

    注释问题

    def chi(food, drink):
        """
        这⾥里里是函数的注释, 先写⼀一下当前这个函数是⼲干什什么的, ⽐比如我这个函数就是⼀一个吃
        :param food: 参数food是什什么意思
        :param drink: 参数drink是什什么意思
        :return: 返回的是什什么东东
        """
        print(food, drink)
        return "very good"
    

    获取函数相关信息

    函数名.__name__可以查看函数的名字
    函数名.__doc__ 可以查看函数的⽂文档注释

    def chi(food, drink):
        """
        这⾥里里是函数的注释, 先写⼀一下当前这个函数是⼲干什什么的, ⽐比如我这个函数就是⼀一个吃
        :param food: 参数food是什什么意思
        :param drink: 参数drink是什什么意思
        :return: 返回的是什什么东东
        """
        print(food, drink)
        """
        这个可以获取到么
        """
        print(chi.__doc__) # 获取函数的⽂文档注释
        print(chi.__name__) # 获取到函数名称
        return "very good"
    chi("吃嘛嘛⾹香", "我不不想吃")
    print(chi.__doc__)
    print(chi.__name__)
    

      我们虽然访问的是target_func函数. 但是实际上执⾏行行的是inner函数. 这样就会给下游的程
    序员带来困惑. 之前不是⼀一直执⾏行行的是target_func么. 为什什么突然换成了了inner. inner是个什什
    么⿁鬼?? 为了了不让下游程序员有这样的困惑. 我们需要把函数名修改⼀一下. 具体修改⽅方案:

    from functools import wraps # 引⼊入函数模块
    # 装饰器器: 对传递进来的函数进⾏行行包装. 可以在⽬目标函数之前和之后添加任意的功能.
    def wrapper(func):
        @wraps(func) # 使⽤用函数原来的名字
        def inner(*args, **kwargs):
            '''在执⾏行行⽬目标函数之前要执⾏行行的内容'''
            ret = func(*args, **kwargs)
            '''在执⾏行行⽬目标函数之后要执⾏行行的内容'''
            return ret
        return inner
    # @wrapper 相当于 target_func = wrapper(target_func) 语法糖
    @wrapper
    def target_func():
        print("我是⽬目标函数")
    # 调⽤用⽬目标函数
    target_func()
    print(target_func.__name__) # 不不再是inner. ⽽而是target_func了了
    @wrapper
    def new_target_func():
        print("我是另⼀一个⽬目标函数")
    new_target_func()
    print(new_target_func.__name__)
    

      

    args和**kwargs什什么时候打散, 什什么时候聚合
    1. 接收参数的时候是聚合, 参数声明
    2. 传递参数的时候是打散, 给函数传递实参

    装饰器参数

    def func(falg):
    #     def wrapper(fn):
    #         def inner(*args,**kwargs):
    #             #判断是否是falg
    #             ret = fn(*args,**kwargs)
    #             #之后的
    #             return ret
    #         return inner
    #     return wrapper
    

     多装饰器装饰一个函数

    def wrapper1(fn):
        def inner(*args, **kwargs):
            print("111")
            ret = fn(*args, **kwargs)
            print("222")
            return ret
        return inner
    def wrapper2(fn):
        def inner(*args, **kwargs):
            print("333")
            ret = fn(*args, **kwargs)
            print("444")
            return ret
        return inner
    @wrapper2
    @wrapper1
    def eat():
        print("我想吃⽔水果")
    eat()
    结果:
    333
    111
    我想吃⽔水果
    222
    444
    

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

     

     for index, element in enumerate(lst): # enumerate 可以直接获取到索引和元素
    #     print(index, element)
    
    # for e in enumerate(lst):
    #     print(e)
    

      

    # s = "提前祝大家生日快乐"
    # bys = s.encode("UTF-8") # 编码
    # print(bys)
    # s1 = bys.decode("UTF-8")    # 解码
    # print(s1)
    
    # 把utf-8 转换成GBK的bytes
    # bys = b'xe6x8fx90'
    # s = bys.decode("utf-8")
    # gbk_bys = s.encode("gbk")
    # print(gbk_bys)
    

      

  • 相关阅读:
    Android_程序未处理异常的捕获与处理
    instanceof关键字
    乐优商城项目爬坑
    [LeetCode]Isomorphic Strings
    [LeetCode]Contains Duplicate II
    [LeetCode]Valid Sudoku
    [LeetCode]Valid Anagram
    [LeetCode]Contains Duplicate
    [LeetCode]Single Number
    [LeetCode]Valid Number
  • 原文地址:https://www.cnblogs.com/lnrick/p/9196614.html
Copyright © 2011-2022 走看看