套娃的装饰器 - 交互式学Python | 莫烦Python

套娃的装饰器

作者: 莫烦 编辑: 莫烦 2021-06-13

Python 的装饰器也十分奇妙,很多时候你并不会想到要用装饰器,但是一旦你知道装饰器可以干什么,能解决什么问题的时候, 你就会爱不释手。

所以它到底是在什么情况下比较好用呢?有这么个前提,装饰器 Decorator 它是装饰一个装饰 Python Function 的东西。 Function 为什么要被装饰?那就是应为我们想为这个 Function 做些额外的事情。但是只为一个 Function 做这件事,那我们还不如直接改掉这个 Function,让它直接干这件事就好了。 Decorator 的好处就是,我们可以给批量的 Function 都做这件事。所以,重点来了, 当你发现,有一批 Function 都要做些前置或者后置的工作,我们可以统一给他们装修,用一个装饰器统一处理。

doll

所以我就会想到俄罗斯的套娃,它就有点像给内部的功能套上一层额外的皮。

为 Function 做额外的事

其实很好理解,我在写 Function 的时候,很常在一个 Function 中调用另一个做些处理。比如下面这样。

而且有时候,我既想做前处理又想做后处理,那么我可以定义两个 inner function。

hamburger

你说,这难道就不像一个汉堡吗?简直一模一样~还真的就是这样理解的。 我们哪些时候需要做前后夹击的处理呢?

  • 比如数据库的处理,来了一条数据,我先要验证这个数据的准确性,然后进行个性化 function 的处理,最后将加工后的数据写入数据库
  • 网页个人页的鉴权,用户每一个点击,我都先需要鉴权,才能做后续不同的 function
  • 。。。

那么这些时候,都存在一个共性,我要对很多不同的 function 做同样的前后处理,这时,就是 Decorator 装饰器有用的时候了。

给一批功能装个修

初次看到 Decorator 的时候,你可能会觉得有点绕,因为他的写法的确不太常见,但是随着你用多了,你就没什么理解压力了。 我们现在尝试给上面那个 outer_fn 外面给包一层前处理的步骤。我会再定义一个装饰器 Decorator Function (wrapper)。 这个 Decorator Function 会将我的 outer_fn 当参数传进来,做一些前处理后,再吐出来。

我们先用一个没有装饰器的方式做一下~

注意,这里我们展示了一个 function 是可以被当做参数传入另一个 function 的。那么有了这个概念后,我们再尝试将它改写成真正的装饰器吧。 下面的代码中,我们使用装饰器有一个特别的写法,就是在你要套娃的 outer_fn 上面写上 @decorator,其实 @ 后面就是你定义的那个装饰器 function 的名字。 比如这里我用的是 def decorator() 那么 @ 后面就是 decorator 这个名字了。寓意着,我要把 decorator 这个 function 套在 outer_fn 外面。

最开始的时候,我们也见识过,除了做 outer_fn 的前处理,我们也能做后处理。这就又回到我们当初的汉堡包操作了。 所以当你想要做汉堡包功能的时候,请你一定要想到 Python 的装饰器,decorator~

最开始我们还提到,在什么情况下,Decorator 才最能发挥出他的价值?答案揭晓了,就是我要对很多 function 做同样汉堡操作的时候,不如说验证一个用户有没有权限使用这个 function。 有权限就在 wrapper 中调用 fn,没权限就跳出。

总结

Decorator 装饰器,是 Python 神奇的一种语法,它的最终目的当然还是减轻你的开发量,特别是针对于不同 function,要做同样的前置处理或后置处理的时候。 用汉堡包的模式将这些 function 包一包,你就能得到便利的功能实现。


降低知识传递的门槛

莫烦很常从互联网上学习知识,开源分享的人是我学习的榜样。 他们的行为也改变了我对教育的态度: 降低知识传递的门槛免费 奉献我的所学正是受这种态度的影响。 通过 【赞助莫烦】 能让我感到认同,我也更有理由坚持下去。