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)

  

 

posted @ 2018-06-18 22:45  又见芳踪  阅读(205)  评论(0编辑  收藏  举报