python中修饰器的优点和作用_Python入门基础教程之装饰器

Python装饰器的定义:在代码运行期间在不改变原函数定义的基础上,动态给该函数增加功能的方式称之为装饰器(Decorator)

装饰器的优点和用途:

1. 抽离出大量函数中与函数功能本身无关的的雷同代码并继续重用。

2. 使用装饰器可以将函数“修饰”为完全不同的行为,可以有效的将业务逻辑正交分解,如用于将权限与身份验证从业务中独立出来。

3. 如果一个函数需要一个功能,且这个功能可以被使用在很多函数上,或是函数并不是自己实现,那可以写个装饰器来实现这些功能。

概况来说,装饰器的作用就是为已经存在的对象添加一些额外的功能。

在学习如何运用装饰器前我们先来学习以下几个知识点:

变量的作用域:

在python中,函数会创建一个自己的作用域或称之为命名空间,结合以下示例来展示函数命名空间的作用域。

示例代码1:

2.变量解析规则:

在python的作用域规则里面,创建变量时一定会在当前作用域里创建同样的变量,但访问或修改变量时,会在当前作用域中查找该变量,如果没找到匹配的变量,就会依次向上在闭合作用域中进行查找,所以也可以在函数中直接访问全局变量。

示例代码2:

3.变量的生存空间:

变量不仅仅是存在于一个个的命名空间中,它们还都有自己的生存周期,全局变量的生存周期是在整个程序执行期间有效,而局部变量的生存周期只在当前作用域中有效,一旦这个作用域不存在了,比如函数执行退出了,变量的生存周期就结束了。

示例代码3:

4.嵌套函数:

定义:嵌套函数就是在函数里面定义函数,而且现有的作用域和变量生存周期依旧不变。

说明:在python里,函数就是对象,它也只是一些普通的值而已。也就是说你可以把函数像参数一样传递给其他的函数或者说从函数了里面返回函数。

示例代码4:

嵌套函数返回函数不加()表示返回函数对象,如下示例5所示:

示例代码5:

5.函数作为变量:

python中函数可以作为参数来传递

示例代码6:

6.闭包:

定义:如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包。

一个函数返回的函数对象,这个函数对象执行需要依赖外部函数的变量值,这个时候函数返回的实际内容如下:

1.函数对象

2.函数对象执行需要使用的外部变量和变量值。

简而言之:闭包就是返回一个函数和一个函数执行所需要的外部变量。

示例代码7:

上例中的inner()函数就是一个闭包,它本身也是一个函数,而且还可以访问本身之外的变量。

每次函数outer被调用时,inner函数都会被重新定义,示例代码7每次返回的函数inner结果都一样,因为name没变。如下例所示,我们将函数稍微改动

一下,结果就不一样了。

示例代码8:

学习了以上6个小知识点,下面开始学习装饰器。

装饰器的定义:

装饰器其实就是一个闭包,把一个函数当做参数后返回一个替代版函数。

装饰器分类:

装饰器分为无参数decorator和有参数decorator

无参数decorator:生成一个新的装饰器函数

有参数decorator:装饰函数先处理参数,再生成一个新的装饰器函数,然后对函数进行装饰。

装饰器的具体定义:

1、把要装饰的方法作为输入参数;

2、在函数体内可以进行任意的操作;

3、只要确保最后返回一个可执行的函数即可(可以是原来的输入参数函数,也可以是一个新函数)

装饰器学习七步法:

第一步:最简单的函数,准备附加额外功能

第二步:使用装饰函数在函数执行前和执行后分别附加额外功能

解析:

1.myfunc = deco(myfunc)执行结果:

before myfunc() called.

myfunc()called.

after myfunc() called.

2.第一次调用myfunc()执行结果:

myfunc()called.

3.第二次调用myfunc()执行结果:

myfunc()called.

从第2和第3次调用myfunc函数来看,并没有实现每次调用都返回第1次调用的效果,那么我们要实现每次调用都带有附加功能的效果,我们后面会=逐步实现。

第三步:使用@符号来装饰函数

第四步:使用内嵌包装函数来确保每次新函数都被调用

上面是实现了1个函数使用装饰器的例子,下面演示2个函数分别使用装饰器的实例:

说明:使用装饰器的函数之间变量不会互相影响,等于每次调用都会重新生成一个_deco函数。

第五步:实现对带参数的函数进行装饰

第六步:对参数数量不确定的函数进行装饰

第七步:装饰器带可变参数

装饰器顺序:

当同时对一个函数使用多个不同的装饰器进行装饰时,这个时候装饰器的顺序就很重要了。

代码示例:

@A

@B

@C

def f():

pass

等价于:

f = A(B(C(f)))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值