首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

装饰器问题知多少

今天给大家带来的分享是装饰器。

装饰器一直以来都是 Python 中很有用、很经典的一个 feature,在工程中的应用也十分广泛,比如日志、缓存等等的任务都会用到。然而,在平常工作生活中,我发现不少人,尤其是初学者,常常因为其相对复杂的表示,对装饰器望而生畏,认为它“too fancy to learn”,实际并不如此。

接下来,让我们进入正文一起学习吧!

函数核心概念

引入装饰器之前,先一起来看一下函数的几个核心概念。

第一点,在 Python 中,函数也是对象。我们可以把函数赋予变量,比如下面这段代码:

这个例子中,我们把函数 func 赋予了变量 send_msg,这样之后你调用 send_msg,就相当于是调用函数 func。

第二点,我们可以把函数当作参数,传入另一个函数中,比如下面这段代码:

第三点,可以在函数里定义函数,也就是函数的嵌套

第四点,函数的返回值也可以是函数对象(闭包)

简单装饰器

首先,先看一个简单装饰器的例子:

当写完这段代码后(函数未被执行、未被执行、未被执行),python解释器就会从上到下解释代码,步骤如下:

def my_decorator(func):  ==> 将my_decorator函数加载到内存

@my_decorator

没错,从表面上看解释器仅仅会解释这两句代码,因为函数在没有被调用之前其内部代码不会被执行。

从表面上看解释器着实会执行这两句,但是 @my_decorator这一句代码里却有大文章,**@函数名** 是python的一种语法糖。

如上例@my_decorator内部会执行一下操作:

执行my_decorator函数,并将 @my_decorator下面的 函数 作为my_decorator函数的参数,即:@my_decorator等价于 my_decorator(func1)所以,内部就会去执行:

将执行完的 my_decorator函数返回值赋值给@my_decorator下面的函数的函数名

然后,将此返回值再重新赋值给func1,即:新func1 = inner

所以,以后业务部门想要执行 func1函数时,就会执行 新func1 函数,在 新func1函数内部k可以先执行其它操作,再执行原来的func1函数,然后将 原来func1 函数的返回值 返回给了业务调用者。如此一来, 即执行了验证的功能,又执行了原来func1函数的内容,并将原func1函数返回值返回给业务调用z者。

因此,如果你的程序中有其它函数需要做类似的装饰,你只需在它们的上方加上@decorator就可以了,这样就大大提高了函数的重复利用和程序的可读性。

带参数的装饰器

你或许会想到,如果原函数 中,有参数需要传递给装饰器怎么办?一个简单的办法,是可以在对应的装饰器函数 wrapper() 上,加上相应的参数,比如:

不过,新的问题来了。如果我另外还有一个函数,也需要使用 my_decorator() 装饰器,但是这个新的函数有两个参数,又该怎么办呢?比如:

事实上,通常情况下,我们会把和,作为装饰器内部函数 wrapper() 的参数。和,表示接受任意数量和类型的参数,因此装饰器就可以写成下面的形式:

带有自定义参数的装饰器

其实,装饰器还有更大程度的灵活性。刚刚说了,装饰器可以接受原函数任意类型和数量的参数,除此之外,它还可以接受自己定义的参数。举个例子,比如我想要定义一个参数,来表示装饰器内部函数被执行的次数,那么就可以写成下面这种形式:

装饰器嵌套

回顾上面的例子,基本都是一个装饰器的情况,但实际上,Python 也支持多个装饰器,比如写成下面这样的形式:

它的执行顺序从里到外,所以上面的语句也等效于下面这行代码:

总结

我是知道,这一期关于装饰器的概念及用法的分享就到这里啦。所谓的装饰器,其实就是通过装饰器函数,来修改原函数的一些功能,使得原函数不需要修改,而实际工作中,装饰器通常运用在身份认证、日志记录、输入合理性检查以及缓存等多个领域中。合理使用装饰器,往往能极大地提高程序的可读性以及运行效率。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20221021A07P0400?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券