Python中装饰器的实现方法以及@wraps内部装饰器的使用

一、不带参数的装饰器

"""
不带参数的装饰器
装饰器 返回函数的函数
      可以写多个
"""


def log(func):
    """记录函数执行的日志"""

    def wrapper():
        print("装饰器1 start...")
        func()
        print("装饰器1 end.")

    return wrapper


def log_in(func):
    """记录函数执行的日志"""

    def wrapper():
        print("装饰器2 start...")
        func()
        print("装饰器2 end.")

    return wrapper


@log
@log_in
def hello():
    """简单功能模拟"""
    print("hello world")


if __name__ == '__main__':
    hello()

运行的结果
执行结果

二、带参数的装饰器

1.添加装饰器的函数没有参数

在原来装饰器的外边嵌套一层装饰器,外部的嵌套的参数可以使用 查看hello()的打印结果

2.函数有参数

有些函数带参数本身就带了参数定义内部装饰器的时候需要传进去
如果函数返回值,内部装饰器先临时保存结果,最后在返回

from functools import wraps


def log(name=None):
    """记录函数执行的日志"""

    def decorator(func):
        @wraps(func)  # 内部提供的装饰器 对以前写好的函数使用装饰器之后的信息不会发生改变
        def wrapper(*args, **kwargs): # 传参使用魔法方法传入
            """装饰器内部的函数"""
            # 内部装饰器对原有的函数名称文档信息发生了改变
            print("{0} start...".format(name))
            print("---wrapper:{0}".format(func.__doc__))  # 在这里查看一下是否已经改变了文档信息
            print("---wrapper:{0}".format(func.__name__))  # 在这里查看一下是否已经改变了函数名称
            temp = func(*args, **kwargs)  # 用临时变量保存结果返回 add函数有返回
            print("{0} end.".format(name))
            return temp

        # wrapper.__doc__ = func.__doc__
        # wrapper.__name__ = func.__name__
        return wrapper

    return decorator


@log('you')  # 这里需要传参数 不传默认None
def hello():
    """简单功能模拟"""
    print("hello world")


if __name__ == '__main__':
    print('doc:{0}'.format(hello.__doc__))  
    print('doc:{0}'.format(hello.__name__))
    hello()

这里@wraps的使用是内部提供的装饰器
需要导入 from functools import wraps,当装饰器内部的wrapper()函数前没有添加@wraps时,在主方法中打印hello()函数的文档信息和名称获取到的是 如下结果

2.1注释掉@wraps执行的结果

得到的hello的文档信息已经发生了改变
注释掉@wraps的结果

2.2添加@wraps的执行结果

添加@wraps的结果

总结一下

1.添加内部提供的装饰器@wraps,可以对以前写好的函数再使用装饰器之后,原本函数的信息不会发生改变,所以每次写装饰器的时候我都添加一下@wraps
2.如果函数带有参数,在装饰器内也要传入参数,使用魔法方法*args,**kwargs在装饰器内部传参
3.函数内不如add()函数有返回值,在装饰器内部用临时变量对结果保存,最后再返回一下

发布了20 篇原创文章 · 获赞 18 · 访问量 8352

猜你喜欢

转载自blog.csdn.net/wankcn/article/details/96163897
今日推荐