美文网首页python遨游记
python装饰器进阶

python装饰器进阶

作者: Maql | 来源:发表于2017-06-28 16:59 被阅读22次

    为什么要使用?

    使用装饰器使代码变得整洁,并且能解决硬编码问题,使用起来也很方便,但是理解起来相对没那么容易,因此写下这篇文章加深理解。下面以记录日志的功能作为装饰器的讲解:

    原始硬编码版

    下面的logit作为装饰器,但是它只能装饰有两个参数的函数,因此是硬编码的。

    def logit(func):
        def decorator(a, b):
            print("func %s is calling " % func.__name__)
            return func(a, b)
        return decorator
    
    @logit()
    def my_add(a, b):
        return a+b
      
    my_add(1, 49)
    

    可变参数版

    使用*args, **kwargs将上述的硬编码去除,使得装饰器能装饰不同的函数

    def logit(func):
        def decorator(*args, **kwargs):
            print("func %s is calling " % func.__name__)
            return func(*args)
        return decorator
    

    wraps通用版

    输出my_add.name发现函数的名称改变了,不是我们想要的my_add,因此使用wraps改造

    print(my_add.__name__)
    
    from functools import wraps
    def logit(func):
        @wraps(func)
        def decorator(*args, **kwargs):
            print("func %s is calling " % func.__name__)
            return func(*args)
        return decorator
    

    自定义参数版

    有时候需要向装饰器来传递参数,例如不同的函数需要不同的日志文件时:

    def logit(log_name="add.log"):
        def decorator(func)
            @wraps(func)
            def wrapper(*args, **kwargs):
                log_str = "func %s is calling " % func.__name__
                print(log_str)
                with open(log_name, "a") as log_file:
                  log_file.write(log_str)
                return func(*args)
            return wrapper
        return decorator
    

    相关文章

      网友评论

        本文标题:python装饰器进阶

        本文链接:https://www.haomeiwen.com/subject/zvwucxtx.html