python语言特性之装饰器

首先,python装饰器的作用是:在不改变原有函数实现的前提下,给此函数增加一些额外的功能(在原有函数调用之前或者调用之后),好像给原有函数加上了一个装饰的壳子

通过一个例子解释python装饰器:

# -*- coding:utf8 -*-

def w1(func):
    def inner(*args,**kwargs):
        print 'w1'
        func(*args,**kwargs)
        print func
    return inner
 
def w2(func):
    print func
    def inner(*args,**kwargs):
        print 'w2'
        func(*args,**kwargs)
    return inner

def w3(func):
    print func
    def inner(*args,**kwargs):
        print 'w3'
        func(*args,**kwargs)
    return inner

@w3
@w2
@w1
def f1(arg1,arg2,arg3):
    print 'f1'

f1(1,2,3)

以上是python多个装饰器使用的例子,目的是为了更好说明装饰器、以及装饰器链的使用,装饰器函数的调用顺序等等。

那么,在使用三个装饰器装饰f1函数,会怎么执行呢,结果如何呢?

首先需要明确一个概念,函数和函数的调用

以上代码中:f1、w1、w2、w3、inner等都是函数,函数其实在内存中就是一个地址。f1(1,2,3)是函数调用。很简单的问题,很容易理解。

第二个概念:语法糖。(@函数名来装饰函数名  只举一个例子:

@w1
def f1(arg1,arg2,arg3):
    print 'f1'

以上代码相当于

def f1(arg1,arg2,arg3):
    print 'f1'

f1 = w1(f1)

注意:f1 = w1(f1) 中,作为参数的f1和返回的f1 已经不是同一个f1了。

好,先看看执行结果:

疑问1:w1 w2 w3三个装饰器的执行顺序是怎么样的?

疑问2:为什么调用了三次装饰器,只调用了一次f1,不应该每调用一次w就调用一次f1吗?

第一个疑问:多个装饰器的调用顺序是自下往上,但是运行时的执行顺序是自上往下!其实只需要记住调用顺序是自下往上,执行顺序可以从调用顺序推出来!同理第二个疑问也可以通过相同办法推出来。

根据以上语法糖的解释,根据自下往上的调用顺序,函数装饰器还可以表示为以下方式:

def f1(arg1,arg2,arg3):
    print 'f1'

f1 = w1(f1) #1 把以上f1作为参数传给w1,再把函数返回值传回给f1(相当于给f1赋了新值,新的值为w1的返回值inner)

f1 = w2(f1) #2 把inner(注意,此时f1已经是w1的返回值inner)作为参数传给w2,并且给f1重新赋新值

f1 = w3(f1) #3 把w2的返回值inner作为参数传给f1,并且给f1重新赋值(w3的返回值inner)

为了更加清楚说明,我们翻译如下:

f1 = w1(最初f1)

f1 = w2(w1函数返回值inner)

f1 = w3(w2函数返回值inner)

此时,我们调用函数f1(1,2,3),其实就是调用了w3里面的inner函数。但是给w3传的参数是w2的返回值inner。等调用到w3中func(*args,**kwargs)函数的时候,其实是调用了w2的内层函数inner。以此类推,直到调用w1内部的func(*args,**kwargs)函数的时候,才是调用的最初的f1函数,所以,其实f1函数只调用了一次,而且是按照w3、w2、w1、f1的顺序执行。

以上就是python装饰器的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值