python装饰器原理

装饰器在python里面使用非常广泛,常用的应用场景,比如可以使用装饰器来做拦截器,或者是在执行某个函数之前,执行另外一个函数,执行完毕之后在执行其他函数,使用装饰器就可以很优雅的解决这种需求。

下面通过例子向你阐述装饰器是如何工作的

假如你定义一个函数,

def foo():
    print 'foo'

python的解释器,去执行这个文件假如你这个python文件叫做test.py ,当你用python解释器去执行这个文件,解释流程是:
从上往下解释。假如你只是定义了函数,但是却没有调用函数,从上往下只是解释完毕了,并不会print 出来。假如你在程序里面调用了,解释到函数的时候,这个函数就会被解释器放到内存里面,执行到函数调用的部分之后,解释器就会到内存当中去找到我们的函数,然后执行里面的内容
调用函数

def foo():
    print 'foo'
 foo()

但是假如你定义两个函数

def f1(arg)
    arg()

def func():
    print 'abc'

f1(func)
看上面:定义了两个函数,注意红色部分的函数调用,我们调用第一个函数的时候,传递进去的参数竟然是一个函数,我们把函数当成参数传递进去了。这样的结构,程序的执行流程就变成了

第一步: 执行到第一个函数f1。然后把函数f1放进内存。函数里面的内容还没有被执行

第二步: 然后再解释到第二个函数,func

第三步: 执行f1(func) 执行f1函数,里面传递了一个参数,这个参数就是函数func,

第四步:执行f1函数的内容,由于传递的参数是一个函数,arg = func函数

第五步:执行arg( ) 由于arg是一个函数,因此后面加一个括号arg( ) 就变成了调用函数,此时函数func被调用了

第六步:执行func函数,然后打印出来 abc

这个就等于装饰器的执行流程,整体的执行流就是,当你想在执行某个函数之前,都进行一些操作装饰器就可以很好的满足需求,举个栗子:
假如你现在有一个程序文件,里面包含了两百个函数,这个两百个函数都是已经写好了,实现某些功能的。你不可以再去修改这个函数,但是你需要在每个函数再执行之前都进行某项操作,比如每个函数执行之前都要进行一下验证。在不能去修改那些函数的情况下,你该怎么做,比如我需要这两百个函数之前之前都验证一下时间,是否和现在的时间相差超过2分钟,你不能去编辑那些函数,怎么做?
这样的情况下,装饰器就可以满足了!
装饰器是什么?装饰器本身就是一个函数,是在函数里面再定义一个函数:
例如:

def Author(arg):
        def inner():
            print 'before'
            arg()
        return inner

func():
    print 'func'

Author(func)
我们这样定义的话,函数的执行流程是:
解释器自顶部向下执行,当执行到Author函数的时候,就会把Author函数放进内存当中,往下执行到解释func函数,把func函数也放到内存里面了,然后到解释Author(func),也就是调用了Author函数,他里面的参数是func函数,然后程序在内存中调用Author来执行。Author的函数体,也就是函数的内容,就解释到了def inner()这个函数,这个函数因为没有被调用所以函数内部的代码不会被执行,最后解释到,return inner 这样是直接将inner返回了。 因此这个Author函数的返回值就是inner函数自身,这样的话我们要是在外面调用这个Author函数的返回值就是相当于执行了 inner。

改成装饰器的写法就是

def Author(arg):
        def inner():
            print 'before'
            arg()
        return inner
@Author
func1():
    print 'func'
@Author
func2():
    print 'func'
@Author
func3():
    print 'func'
@Author
func4():
    print 'func'
@Author
func5():
    print 'func'
@Author
func6():
    print 'func'
@Author
func7():
    print 'func'

添加上一个@Author之后,python解释器做的操作就是,将@Author下面的函数当做参数传递到装饰器里面,然后装饰器获取到自己本身内部的返回值,在我们这个栗子里面就是,返回了一个函数inner。装饰器将这个返回值给到所有使用了装饰器的函数的函数名.
然后被装饰的函数依旧像之前那样调用,只不过调用的时候会执行一下装饰器,然后才执行我们的函数

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值