python装饰器进阶

为什么要使用?

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

原始硬编码版

下面的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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,107评论 19 139
  • 呵呵!作为一名教python的老师,我发现学生们基本上一开始很难搞定python的装饰器,也许因为装饰器确实很难懂...
    TypingQuietly阅读 19,788评论 26 186
  • 原文出处: dzone 译文出处:Wu Cheng(@nullRef) 1. 函数 在python中,函数通过...
    DraculaWong阅读 3,541评论 0 3
  • Python的装饰器的英文名叫Decorator,要对一个已有的模块做一些“修饰工作”,所谓修饰工作就是想给现有的...
    Spareribs阅读 3,895评论 1 11
  • 日复一日,年复一年,见过人的出生,也见过人的死亡,有时不经会想人这一生究竟是为了什么。
    weylan阅读 1,247评论 0 1

友情链接更多精彩内容