python面向对象之装饰器

装饰器是什么

装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。甚至,有人这样说:"内裤可以用来遮羞,但是到了冬天没法为我们防风御寒,聪明的人发明了长裤,有了长裤以后就不会再冷了。装饰器就是我们这里说的长裤,在不影响内裤作用的前提下,给我们的身体提供了保暖的功效。"

为什么需要装饰器

先看一个简单的例子

def test_one():
    print("test_one")

现在有个需求,希望可以输出函数的执行日志,这时,有人会这样实现:

def test_one():
    print('test_one')
    print('test_one is running')

但是,如果有其他的函数需要这功能,那么会出现很多的重复代码,为了减少代码的重复,我们需要创建一个专门的记录日志的函数,谁需要执行日志,就把谁作为参数传递。

def print_log(func):
    print('函数正在运行中...')
    func()

def test_one():
    print("test_one")


print_log(test_one)

按照上述代码将函数作为参数传递,需然可以实现功能,但是却破坏了原有代码的逻辑结构。如果要求已经实现的函数,不能修改,只能扩展,即遵守“封闭开放”原则,那么是不允许在函数内部进行修改。
装饰器可以满足上述需求。在python中,装饰器的语法是已@开头,下面,我们写一个简单的装饰器。

def wrap(func):
    print('正在装饰')
    def inner():
        print("正在验证权限")
        func()
    return  inner

@wrap
def test():
    print("test")

test()

下面我们来分析一下程序的执行过程:
1、当程序执行test()时,发现函数test()上面有装饰器@wrap,所以会执行@wrap。@wrap等价与test=wrap(test),他可以拆分为两步:
①执行wrap(test),将函数名test作为参数传递给wrap.在调用wrap函数的过程中,首先执行print语句,输出“正在装饰”,然后会将形参func执行test()函数体,并将inner()函数的引用返回给wrap(test),作为wrap(test)的返回值。
②将warp(test)的返回值赋给test,此时,test指向inner()函数,到此完成了函数test()的装饰。
2、调用test()指向的函数。因为test指向的是inner()函数,所以此时,调用test()函数相当于调用inner()函数,输出如下:
①输出pirnt语句:“正在验证权限”
②调用func指向的函数,输出“test”

你可能感兴趣的:(python面向对象之装饰器)