美文网首页
Python装饰器应用于日志输出

Python装饰器应用于日志输出

作者: dnsir | 来源:发表于2018-11-19 22:06 被阅读74次

    1 入门

    装饰器应该是Python里面最难理解的概念了,网络很多文章和教程都试图把装饰器讲的很明白,其实是讲明白了,但对于没有实际项目开发经验的人来说装饰器不容易掌握,且在日常业务开发中,尽快将业务开发完成上线才是首要任务,代码质量往往成为其次,偶尔闲来需要不断补充新的知识而不是细细品味已经上线的代码。

    2 函数装饰器

    既然是装饰,那么就是在函数真正执行之前(或者之后)进行一些装饰(包裹),装饰可以对函数的输入参数,也可以在函数运行之前进行一些操作,也可以在函数运行之后进行一些操作,装饰器只是一个语法糖语法糖,就是这样写就是这样的结果,为什么是这样的结果?没有为什么)。

    3 接近实际的例子

    以日志输出为例,在日志系统设计中,往往会设计如下几个函数:

    def debug(msg):
        msg = "debug " + msg
        print(msg)
    
    def info(msg):
        msg = "info " + msg
        print(msg)
    

    如果有很多日志级别如error,warn,trace等,那么msg = "debug" + msg将会重复又重复,这个时候装饰器是可以派上用场,如之前所说,装饰器可以在函数执行之前对参数进行一些操作,这里主要就是对输入参数msg进行操作,突然感觉装饰器也有点类似C++的模板,方便代码复用,当然这也是装饰器的重要意义。

    4 使用装饰器

    使用装饰器将提取一个wrapper函数(包裹函数),使用语法糖@do_log完成装饰器的使用。

    from functools import wraps
    
    def do_log(func):
        @wraps(func)
        def wrapper(*args, **kw):
            if func.__name__ == "debug":
                msg = "debug {}".format(args[0])
            elif func.__name__ == "info":
                msg = "info {}".format(args[0])
            else:
                msg =  "unknown {}".format(args[0])
            return func(msg, **kw)
        return wrapper
    
    @do_log
    def debug(msg):
        print(msg)
    
    @do_log
    def info(msg):
        print(msg)
    
    if __name__ == "__main__":
        debug("123")
        info("abc")
    

    当然这个例子还有许多地方值得完善,比如参数直接使用了args[0]等,其实装饰器只是帮我们做了一件事情,即通过语法糖实现了 debug = do_log(debug),然后debug("123"),执行的是wrapper("123")。当然实际实现会比这里所说的略微复杂,但是大体如此。

    5 总结

    装饰器虽然是Python的重要语法糖,但是阅读开源代码来看使用没有那么普通,上述例子通过函数封装可以实现同样的工作,除非是已经习惯装饰器这种语法糖。

    相关文章

      网友评论

          本文标题:Python装饰器应用于日志输出

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