Python中的装饰器是什么

什么是装饰器

装饰器是程序开发中经常会使到的一个功能,所以这也是Python面试中必问的问题。

定义:

装饰器本身就是一个函数,为其他函数提供附加功能,不改变被修饰函数的源代码,不改变原调用方式,装饰器=高阶函数+嵌套函数。

知识点:

函数本身就是一个变量(意味着可以被复制给一个变量:test=test(1) )。

高阶函数:把函数名当成一个实参传递给另一个函数func(test1) (不改变源代码的前提下添加代码)。

返回值中包含函数名return deco (不改变函数的调用方式)。

嵌套函数:函数中加入新的函数。

典型结构:

def func(args):
    def func_in(args_in):
         pass
     return func_in

三、装饰器案例

1、先看一个例子

某公司有多个研发部门,1个基础平台部门,基础平台负责提供底层的功能,如:数据库操作、redis调用、监控API等功能。研发部行使基础功能时,只需调用基础平台提供的功能即可。如下:

--------------基础平台提供的功能--------------
def func1():
    pass
def func2():
    pass
def func3():
    pass
--------------研发部门A使用基础平台--------------
func1()
func2()
func3()
--------------研发部门B使用基础平台--------------
func1()
func2()
func3()

随着项目进度的深入,产品经理提出,要在基础平台的提供的所有功能中,添加验证功能,不能谁都可以使用基础平台的全部功能,即执行功能前,先进行验证。

项目经理将此功能交给了小A去实现。

小A就去和每个研发部沟通,让每个研发部自己把验证的代码加上,结果第二天就被辞职了。

项目经理又将此功能交给了小B去实现。

小B吸取小A的经验,开始自己改代码:

--------------基础平台提供的功能--------------
def func1():
    #验证1
    #验证2
    pass
def func2():
    #验证1
    #验证2
    pass
def func3():
    #验证1
    #验证2
    pass
--------------研发部门A使用基础平台--------------
func1()
func2()
func3()
--------------研发部门B使用基础平台--------------
func1()
func2()
func3()

没过多久小B也被开除了。。。

相关推荐:《Python相关教程》

项目经理又把工作交给了小C,小C对基础平台代码进行重构,其他业务部门无需做任何修改。

--------------基础平台提供的功能--------------
def check_login():
    #验证1
    #验证2
    pass
def func1():
    check_login()
    pass
def func2():
    check_login()
    pass
def func3():
    check_login()
    pass
--------------研发部门A使用基础平台--------------
func1()
func2()
func3()
--------------研发部门B使用基础平台--------------
func1()
func2()
func3()

项目经理看后表示还不错,但是感觉还是差了一点点,于是决定不再低调,再也不让小弟做了,于是自己做了一个方案:

--------------基础平台提供的功能--------------
def check_login(func):
    def inner():
        #验证1
        #验证2
        func()
    return inner
@check_login
def func1():
    pass
@check_login
def func2():
    pass
@check_login
def func3():
    pass
--------------研发部门A使用基础平台--------------
func1()
func2()
func3()
--------------研发部门B使用基础平台--------------
func1()
func2()
func3()

对于上述代码,也是仅仅对基础平台的代码进行修改, func1(), func2(), func3()之前都进行【验证】操作,并且其他研发部也无需做任何操作。

单独以func1()为例讲解:

def check_login(func):
    def inner():
        #验证1
        #验证2
        func()
    return inner
@check_login
def func1():
    pass

python解释器就会从上到下解释代码,步骤如下:

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

2 @check_login

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

上例@check_login内部会执行以下操作:

执行check_login函数,并将@check_login下面的函数作为check_login函数的参数,

即@check_login等价于check_login(func1),所以内部就会去执行:

def check_login(func):
    def inner():
        #验证1
        #验证2
        func() #func是参数。此时的func就是函数func1()
    #返回inner,inner的内部就是执行func1()函数,但是执行func1()函数前,进行了验证1,验证2
    return inner

check_login() 的返回值

将执行完的chenk_login函数返回值赋值 给@check_login下面的函数的函数名func1 即将check_login()的返回值再重新赋值给func1,即:

新func1 = def inner():
            #验证1
            #验证2
            func() #func是参数。此时的func就是函数func1()
            #返回inner,inner的内部就是执行func1()函数,但是执行func1()函数前,进行了验证1,验证2
            return inner

所以,以后研发部门想要执行func1函数时,就会执行新func1函数,在新func1函数内部先执行验证,再执行原来的func1函数,然后将原来func1函数的返回值返回给了业务调用者。

来源:PY学习网:原文地址:https://www.py.cn/article.html