python装饰器听了N次也没印象,读完这篇你就懂了

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python装饰器听了N次也没印象,读完这篇你就懂了相关的知识,希望对你有一定的参考价值。

参考技术A 装饰器其实一直是我的一个"老大难"。这个知识点就放在那,但是拖延症。。。

其实在平常写写脚本的过程中,这个知识点你可能用到不多

但在面试的时候,这可是一个高频问题。

所谓的装饰器,其实就是通过装饰器函数,来修改原函数的一些功能,使得原函数不需要修改。

这一句话理解起来可能没那么轻松,那先来看一个"傻瓜"函数。

放心,绝对不是"Hello World"!

怎么样,没骗你吧? 哈哈,这个函数不用运行相信大家都知道输出结果: "你好,装饰器" 。

那如果我想让 hello() 函数再实现个其他功能,比如多打印一句话。

那么,可以这样"增强"一下:

运行结果:

很显然,这个"增强"没啥作用,但是可以帮助理解装饰器。

当运行最后的 hello() 函数时,调用过程是这样的:

那上述代码里的 my_decorator() 就是一个装饰器。
它改变了 hello() 的行为,但是并没有去真正的改变 hello()函数 的内部实现。

但是,python一直以"优雅"被人追捧,而上述的代码显然不够优雅。

所以,想让上述装饰器变得优雅,可以这样写:

这里的 @my_decorator 就相当于旧代码的 hello = my_decorator(hello) , @ 符号称为语法糖。

那如果还有其他函数也需要加上类似的装饰,直接在函数的上方加上 @my_decorator 就可以,大大提高函数
的重复利用与可读性。

输出:

上面的只是一个非常简单的装饰器,但是实际场景中,很多函数都是要带有参数的,比如hello(people_name)。

其实也很简单,要什么我们就给什么呗,直接在对应装饰器的 wrapper() 上,加上对应的参数:

输出:

但是还没完,这样虽然简单,但是随之而来另一个问题:因为并不是所有函数参数都是一样的,
当其他要使用装饰器的函数参数不止这个一个肿么办?比如:

没关系,在python里, *args 和 **kwargs 表示接受任意数量和类型的参数,所以我们可以这样
写装饰器里的 wrapper() 函数:

同时运行下 hello("老王") ,和 hello3("张三", "李四") ,看结果:

上面2种,装饰器都是接收外来的参数,其实装饰器还可以接收自己的参数。
比如,我加个参数来控制下装饰器中打印信息的次数:

注意,这里 count 装饰函数中的2个 return .
运行下,应该会出现3次:

现在多做一步 探索 ,我们来打印下下面例子中的hello()函数的元信息:

输出:

这说明了,它不再是以前的那个 hello() 函数,而是被 wrapper() 函数取代了。

如果我们需要用到元函数信息,那怎么保留它呢?这时候可以用内置装饰器 @functools.wrap 。

运行下:

好记性不如烂笔头,写一下理解一下会好很多。
下面还分享类的装饰器,以及装饰器所用场景。

以上是关于python装饰器听了N次也没印象,读完这篇你就懂了的主要内容,如果未能解决你的问题,请参考以下文章

Nginx可以做什么?看完这篇你就懂了

大话「 非对称加密」,看完这篇你就懂了

Nginx可以做什么?看完这篇你就懂了

CDN到底是个什么鬼?看完这篇你就懂了

深度分析:锁升级过程和锁状态,看完这篇你就懂了!

Android程序员如何跨35岁这道坎?看完这篇你就懂了