python带参数装饰器的两种写法

python带参数装饰器的两种写法

前言

最近在实现一个装饰器的过程中发现了一个很有意思的地方,在博客里面分享出来

不同的写法

  • 三层函数嵌套,实现了可传参数的一个装饰器。

    import logging
    import functools
    
    def logger(msg=None):
        """日志"""
        def dector(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                result = func(*args, **kwargs)
                logging.info(func.__name__ + func.__doc__)
                logging.info(f"参数:{args}{kwargs}")
                if msg:
                    log.info(msg.format(result))
                return result
            return wrapper
        return dector
    
  • 使用functools.partial函数实现了一个比较抽象的三层带参数装饰器。

    import logging
    import functools
    
    def loggers(func=None, msg=None):
        """日志"""
        if func is None:
            return functools.partial(loggers, msg=msg)
    
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            result = func(*args, **kwargs)
            logging.info(func.__name__ + func.__doc__)
            logging.info(f"参数:{args}{kwargs}")
            if msg:
                log.info(msg.format(result))
            return result
    
        return wrapper
    

有何异同

可以看到从代码的阅读层面来讲,第一个写法是比较易读的,第二种写法不容易阅读。从执行调用方面第二种更简单点。

先看以下第一种调用执行的方式:

  • 第一种写法

    • 装饰器传参数

      image-20201003175359588

    • 装饰器不传参数

    image-20201003174759331

  • 第二种写法

    • 装饰器不带参数

      image-20201003175115480

    • 装饰器带参数

      image-20201003175212459

可以看到使用了functools.partial函数的装饰器,在调用非必填参数时,可以不用使用括号。

除了写法理解比较抽象,这样的调用还是比较友好的。

原文地址:https://www.cnblogs.com/wxhou/p/13765001.html