Python学习笔记——Decorator装饰器

参考文章:详解Python的装饰器

理解装饰器

  1. 原始简单程序

     def say_hello():
         print "hello!"
    
    def say_goodbye():
        print "hello!"  # bug here
    
    if __name__ == '__main__':
        say_hello()
        say_goodbye()
    
  2. 要求调用每个方法前都要记录进入函数的名称:
    法一(low):

    def say_hello():
          print "[DEBUG]: enter say_hello()"
          print "hello!"
    
    def say_goodbye():
          print "[DEBUG]: enter say_goodbye()"
          print "hello!"
    
    if __name__ == '__main__':
          say_hello()
          say_goodbye()
    

    法二:

    def debug():
           import inspect
           caller_name = inspect.stack()[1][3]
           print "[DEBUG]: enter {}()".format(caller_name)   
    
    def say_hello():
            debug()
            print "hello!"
    
    def say_goodbye():
            debug()
            print "goodbye!"
    
    if __name__ == '__main__':
            say_hello()
            say_goodbye()
    

    每个函数里都要调用一下debug()函数。

    法三(装饰器):

    def debug(func):
          def wrapper():
                print "[DEBUG]: enter {}()".format(func.__name__)
                return func()
          return wrapper
    
    def say_hello():
          print "hello!"
    
    say_hello = debug(say_hello)  # 添加功能并保持原函数名不变
    

    上面的debug函数其实已经是一个装饰器了,它对原函数做了包装并返回了另外一个函数,额外添加了一些功能。因为这样写实在不太优雅,在后面版本的Python中支持了@语法,下面代码等同于上面的写法。

    def debug(func):
          def wrapper():
                print "[DEBUG]: enter {}()".format(func.__name__)
                return func()
         return wrapper
    
    @debug
    def say_hello():
          print "hello!"
    
  3. 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
    概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。

带参数的装饰器

  • 上面程序中的装饰器是最简单的装饰器,但是有一个问题,如果被装饰的函数需要传入参数,那么这个装饰器就坏了。Python提供了可变参数*args和关键字参数**kwargs,有了这两个参数,装饰器就可以用于任意目标函数了。

     def debug(func):
           def wrapper(*args, **kwargs):  # 指定参数
                 print "[DEBUG]: enter {}()".format(func.__name__)
                 print 'Prepare and say...',
                 return func(*args, **kwargs)
           return wrapper  # 返回
    @debug
    def say(something):
          print "hello {}!".format(something)
    
    say('w')
    

    结果:
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值