python装饰器以及装饰器的深入

本节主要内容:

1. 通⽤装饰器回顾

2. 函数的有⽤信息

3. 带参数的装饰器

4. 多个装饰器同时装饰⼀个函数

 

1.通⽤装饰器回顾

通过装饰器的模板格式:

def wrapper(fn):

  def inner(*args,**kwargs):

    #增加的内容

    ret = fn(*args,**kwargs)

    #增加的内容

    return ret

   return inner

@wrapper

2. 函数的有⽤信息

(1)获取函数的注释信息,

示例:

def fun(a,b,c):
    """
    函数的功能:
    :param a: 具体传的参数
    :param b: 具体传的参数
    :param c: 具体传的参数
    :return: 返回值
    """
print(fun.__doc__)

"""
执行结果如下:
    函数的功能:
    :param a: 具体传的参数
    :param b: 具体传的参数
    :param c: 具体传的参数
    :return: 返回值
    
"""

(2)获取函数的函数名

def fun(a,b,c):
    """
    函数的功能:
    :param a: 具体传的参数
    :param b: 具体传的参数
    :param c: 具体传的参数
    :return: 返回值
    """
print(fun.__name__)

这里有个问题,如果是函数调用了装饰器的话,会返回装饰器的内置函数的信息,并不会返回用户函数的信息.

如下:

def wrapper(fn):
    def inner(*args,**kwargs):
        print("test")
        ret = fn(*args,**kwargs)
        return ret
    return inner
@wrapper
def fun(a,b,c):
    """
    函数的功能:
    :param a: 具体传的参数
    :param b: 具体传的参数
    :param c: 具体传的参数
    :return: 返回值
    """
print(fun.__name__)

"""
这里打印的是inner
"""

怎么才能打印到原来的函数的doc和name呢,这里需要加入额外的装饰器

示例如下:

from functools import wraps
def wrapper(fn):
    @wraps(fn)
    def inner(*args,**kwargs):
        print("test")
        ret = fn(*args,**kwargs)
        return ret
    return inner
@wrapper
def fun(a,b,c):
    """
    函数的功能:
    :param a: 具体传的参数
    :param b: 具体传的参数
    :param c: 具体传的参数
    :return: 返回值
    """
print(fun.__name__)

 

 

3. 带参数的装饰器

如果想对增加的功能进行判断,这时需要加入参数来实现的,示例如下:

def wrapper_out(flag):
    def wrapper(fn):
        def inner(*args,**kwargs):
            if flag == True:
                print("前面增加的内容")
                ret = fn(*args,**kwargs)
                print("后面增加的内容")
                return ret
            else:
                ret = fn(*args,**kwargs)
                print("后面增加的内容")
                return ret
        return inner
    return wrapper
@wrapper_out(False)
def fun():
    print("123")
fun()

 

4. 多个装饰器同时装饰⼀个函数

多个装饰器装饰的结果请按如下公式来读取

[(目标)]

其中目标就是目标函数,()就是最靠近的装饰器,[]是上层的

示例

def wrapper1(fn):
    def inner(*args,**kwargs):
        print("开始1")
        ret = fn(*args,**kwargs)
        print("结束1")
        return ret
    return inner
def wrapper2(fn):
    def inner(*args,**kwargs):
        print("开始2")
        ret = fn(*args,**kwargs)
        print("结束2")
        return ret
    return inner
@wrapper2
@wrapper1
def func():
    print("我是fun1")
func()

 

 

一些额外的补充:

 

enumerate()这个是求一个列给或者元组的索引和对应的元素的值
示例:
lst = ["a","b","c","d"]
for i,e in enumerate(lst):
    print(i,e)

如果不加解构的话,返回的是元组,示例如下

lst = ["a","b","c","d"]
for i in enumerate(lst):
    print(i)

"""
(0, 'a')
(1, 'b')
(2, 'c')
(3, 'd')
"""

 

关于编解码:

示例:

s = "我是一个好人"
#编码成bytes类型
bys = s.encode("utf-8")
print(bys)
#如果想把bytes的utf-8转成gbk,需要如下操作
print(bys.decode("utf-8").encode("gbk"))

 

posted @ 2018-06-15 14:41  auxiaoliu  阅读(119)  评论(0编辑  收藏  举报