其他分享
首页 > 其他分享> > 02-装饰器

02-装饰器

作者:互联网

引入

在web开发中,我们希望我们的视图函数只负责业务逻辑就好了,这个代码越精炼越好,然而实际上很多页面的请求必须登陆了才能返回,因此大多数页面在请求之前我们都要先判断一下是否登录了,没有登陆的话还要先转到登录页面。能不能把这部分判断代码和主体业务逻辑分割开来。

能,这就是装饰器模式,装饰器模式就是将一段核心代码封装一下,丰富了它的功能,使之更为强大。不过python相对其它的语言完成装饰器模式更为简洁。

装饰器如何使用

def outer(func):
    print('outer_begin')

    def inner(*args, **kwargs):
        print('inner_begin')
        func()
        print('inner_end')

    print('outer_end')
    return inner


@outer
def log():
    print('log-----')


print('#########################')
log()

# 结果
outer_begin
outer_end
#########################
inner_begin
log-----
inner_end

python是一门解释型语言,从上往下执行,先打印的是outer_begin,outer_end,在python里面函数名带上小括号才是调用,才会真的执行。也就是说,函数正主还没开始执行呢,outer函数就已经跑了一遍。

python解释器遇到@outer,会将下面的log函数装饰一下,将log当做参数传到outer函数里面,也就是说装饰器的参数必须是个函数,在outer内部定义了一个内部函数inner,真正的log是在inner内执行的。也就是说outer函数用inner函数把log函数包裹了一下。outer函数最后返回了inner函数,只返回了一个函数名是不会执行的。从此以后在这个可执行文件里面,但凡我们调用log函数的时候,真正执行的是inner函数,怎么证明呢,python有个内置字段__name__可以获取当前对象的名字。

print(log.__name__)

# 输出
inner

说明现在的log已经变成了inner。而这一切在这个文件的代码真正执行以前就已经完成了替换,outer_begin,outer_end就是明证。而inner_begin,log-----,inner_end分别代表,核心代码执行之前的准备工作,核心逻辑,收尾工作。这就是一个简单的装饰器。

一般的,outer_begin,outer_end这两块是没有的,装饰器的形式是这样的

def outer(func):

    def inner(*args, **kwargs):
        print('inner_begin')
        func()
        print('inner_end')

    return inner

多个装饰器的执行顺序

def outer1(func):

    def inner1(*args, **kwargs):
        print('inner1_begin')
        func()
        print('inner1_end')

    return inner1


def outer2(func):

    def inner2(*args, **kwargs):
        print('inner2_begin')
        func()
        print('inner2_end')

    return inner2


@outer1
@outer2
def log():
    print('log-----')


log()

# 结果
inner1_begin
inner2_begin
log-----
inner2_end
inner1_end

执行的顺序是,核心代码执行之前,从上到下执行,核心代码执行以后,从下向上执行

标签:02,begin,outer,log,inner,print,end,装饰
来源: https://www.cnblogs.com/yaowy001/p/15924383.html