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'\xe6\x8f\x90' # s = bys.decode("utf-8") # gbk_bys = s.encode("gbk") # print(gbk_bys)