[Python] 装饰器(一)

2021-11-09  本文已影响0人  紫藤lvy

1. 装饰器是什么?
装饰器(Decorator )作为python语言面试的必免考点!如果没有回答上来,在面试官心中你的技术就大打折扣!
首先从字面上去理解,装饰就是修饰,点缀的意思。相当于是函数功能的扩展。
装饰器本质上也是Python的函数,其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
2. 装饰器应用场景
切面需求的场景,
比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
进一步说:装饰器的作用就是为已经存在的对象添加额外的功能。
3. 装饰器背景
首先看一个函数

def driving():
      print("i'm driving")

现在有一个新的需求,希望可以记录下函数的执行日志,于是在代码中添加日志代码:

def driving():
      print("i'm driving")
      logging.info("driving is running")

假设stoping , parking 都有类似的需求。难道也把每个logging函数写道函数内部?这样就会造成大量的冗余代码。如何必免这样的情况产生?
重新定义一个函数:专门处理日志 ,日志处理完之后再执行真正的业务代码。

def  record_logging(func):
       logging.info("%s is running" % func.__name__)
       func()

def driving():
      print("i'm driving")

record_logging(driving):

逻辑上很清晰, 但是如果这样做,每次都要将一个函数作为参数传递给record_logging函数。并且这样做破坏原来的函数结构。之前运行的driving 函数,现在需要运行 record_logging函数。
如何在不破坏原来的函数基础,实现这样的功能? 答案就是装饰器的使用。

4. 装饰器使用

def  record_logging(func):
         def wrapper(*args, **kwargs):
              logging.info("%s is running" % func.__name__)
              return func(*args, **kwargs)
        return wrapper

def driving():
      print("i'm driving")

driving = record_logging(driving)
driving ()

函数record_logging 就是装饰器,真正执行的业务函数driving 被包含在里面了,看上去 driving 被函数record_logging 装饰了。
@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操。

def  record_logging(func):
         def wrapper(*args, **kwargs):
              logging.info("%s is running" % func.__name__)
              return func(*args, **kwargs)
        return wrapper

@record_logging
def driving():
      print("i'm driving")

@record_logging
def stoping():
      print("i'm stoping")


driving()
stoping()

加入@ 语法糖之后,就能省略driving = record_logging(driving)
这一步骤。如果有其它类似的函数调用就可以直接用装饰器。提高了程序的可重复利用性,并增加了程序的可读性。

上一篇下一篇

猜你喜欢

热点阅读