Python装饰器

装饰器介绍

谈装饰器之前,需明白一件事,Python中的函数和Java、C++不一样,Python中的函数可以像普通变量一样当做参数传递给另外一个函数,代码示例如下:

def foo():
    print('hello world')
def decorator(function):
    function()
decorator(foo)

装饰器本质上是一个能返回函数的高阶函数它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。 
简单装饰器示例代码如下:

import logging
def use_logging(func):
    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()
    return wrapper
def foo():
    print('I am foo')
foo = use_logging(foo) # 因为装饰器 use_logging(foo) 返回的时函数对象 wrapper,这条语句相当于 foo = wrapper
foo()

程序输出如下:

WARNING:root:foo is running 
I am foo

@语法糖

Python内置的@property 装饰器是负责把一个方法变成属性调用的,有了@,就可以省去foo = use_logging(foo)这一句,直接调用foo()即可实现相同的功能。

def use_logging(func):
    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()
    return wrapper
@use_logging
def foo():
    print("i am foo")
foo()

有了Python的@语法,把decorator置于函数foo定义处,调用foo函数,相当于执行语句foo = use_logging(foo)

args、*kwargs,可变参数与关键字参数

可以在定义wrapper函数的时候指定参数,参数可以是可变参数*args、关键字参数**kwargs。

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。

给wrapper函数添加参数的示例代码如下:

def wrapper(*args, **kwargs):
        # args是一个数组,kwargs一个字典
        logging.warn("%s is running" % func.__name__)
        return func(*args, **kwargs)
    return wrapper

带参数的装饰器

装饰器还有更大的灵活性,例如带参数的装饰器,在上面的装饰器调用中,该装饰器接收唯一的参数就是执行业务的函数 foo 。装饰器的语法允许我们在调用时,提供其它参数,比如@decorator(a)。示例代码如下:

def use_logging(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if level == "warn":
                logging.warn("%s is running" % func.__name__)
            elif level == "info":
                logging.info("%s is running" % func.__name__)
            return func(*args)
        return wrapper
    return decorator
@use_logging(level="info")
def foo(name='foo'):
    print("i am %s" % name)
foo()

程序输出如下:

i am foo

装饰器示例

可打印函数运行时间的装饰器,代码如下:

# decorator: print the cost time of run function
def runTime(func):
   def wapper(arg, *args, **kwargs):
      print("function name: %s" %func.__name__)
      start = time.time()
      res = func(arg, *args, **kwargs)
      end = time.time()
      print("run time: %.2fs" %(end - start))
      print("="*30)
      return res
   return wapper

总结

实现装饰器知识储备: 
a、函数即“变量” 
b、高阶函数 
c、函数嵌套 
d、高阶函数+嵌套函数==》装饰器 
在面向对象( OOP)的设计模式中, decorator 被称为装饰模式。 OOP的装饰模式需要通过继承和组合来实现,而 Python 除了能支持 OOP 的decorator外,直接从语法层次支持 decorator。Python的decorator可以用函数实现,也可以用类实现。

参考资料

理解Python装饰器看这一篇就够了

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值