美文网首页
理解装饰器的各种执行细节

理解装饰器的各种执行细节

作者: 那未必 | 来源:发表于2017-10-05 16:30 被阅读218次

当装饰器遇上尾递归函数

如果一个尾递归函数套用了装饰器,那么当一次递归发生后,是尾递归内部的代码先执行,还是装饰器中尾递归函数之后的代码先执行?具体看下面的代码:

def deco(func):
    def handler(*args,**kwargs):
        print 'inside decorator, begin to decorate...'
        # func 内部有打印语句
        # 在递归发生时,究竟是 func内部的打印语句先执行
        # 还是下面的 end of decorate 先执行?
        func(*args,**kwargs)
        print 'end of decorate!'
    return handler

@deco
def adding(count=0):
    print 'count=',count
    if count<3:
        return adding(count+1)
    else:
        print 'count is equal to 3. stop'

adding()
inside decorator, begin to decorate...
count= 0
inside decorator, begin to decorate...
count= 1
inside decorator, begin to decorate...
count= 2
inside decorator, begin to decorate...
count= 3
count is equal to 3. stop
end of decorate!
end of decorate!
end of decorate!
end of decorate!

结论

如果装饰器内部,在尾递归函数的执行代码之后还有其他代码,那么这些代码必须等到尾递归内部的代码执行完毕之后才会执行。

某些使用场景下,可能我们还需要在装饰器内部对于被装饰方法传入的某个参数进行修改,那么该如何获取指定的参数呢?

其实只要打印一下 args 和 kwargs 就明白如何使用了。

def response_validate(func):
    def decorate(*args,**kwargs):
        print 'now decorating...'
        args=list(args)
        args[0]='tell'
        print args
        print 'args 是元组,不能直接修改变量除非修改为 list;kwargs 是字典,可以修改'
        if kwargs.get('count')!=None:
            print 'kwargs[\'count\']=',kwargs['count']
            kwargs['count']+=1
            print '修改后kwargs[\'count\']=',kwargs['count']
        r=func(*args,**kwargs)
        print 'decorated!'
        return r
    return decorate

def main(s,count=0):
    @response_validate
    def test(s,count=0):
        print 'inside decorated func...s=',s
        print 'inside decorated func...count=',count
        return count + 1
    return test(s,count=count)

main('main',count=3)
now decorating...
['tell']
args 是元组,不能直接修改变量除非修改为 list;kwargs 是字典,可以修改
kwargs['count']= 3
修改后kwargs['count']= 4
inside decorated func...s= tell
inside decorated func...count= 4
decorated!

5

类装饰器的创建和使用方法

类装饰器与普通装饰器的差别在于类装饰器可以拦截类内部的方法,在执行诸如 init, getattr 等方法之前或之后植入逻辑代码。

def Tracer(aClass):
    class Wrapper:
        def __init__(self,*args,**kwargs):
            self.fetches=0
            self.wrapped=aClass(*args,**kwargs)
        def __getattr__(self,attr_name):
            print 'Tracer attrname=',attr_name
            self.fetches+=1
            return getattr(self.wrapped,attr_name)
    return Wrapper

@Tracer
class Spam:
    def __init__(self):
        self.name='spamee'
    def display(self):
        print 'Spam class'

sp=Spam()
sp.display()
sp.display()
sp.name

Tracer attrname= display
Spam class
Tracer attrname= display
Spam class
Tracer attrname= name


'spamee'

相关文章

  • 理解装饰器的各种执行细节

    当装饰器遇上尾递归函数 如果一个尾递归函数套用了装饰器,那么当一次递归发生后,是尾递归内部的代码先执行,还是装饰器...

  • Python - 学习理解带参数的装饰器

    理解带参数的装饰器 参考文章 Python精进-装饰器与函数对象 加了装饰器这段代码从一个函数定义(不会执行任何东...

  • python3基础---详解装饰器

    1、装饰器原理 2、装饰器语法 3、装饰器执行的时间 装饰器在Python解释器执行的时候,就会进行自动装饰,并不...

  • 多个装饰器存在时的执行顺序

    装饰器的执行顺序是怎样的? 装饰器函数的执行顺序分为定义阶段和执行阶段,装饰器函数在被装饰函数定义好后立即执行 在...

  • Python之——装饰器

    这也是看了好多次忘了好多次又看了好多次的概念。写个笔记。 上面代码理解装饰器执行行为可理解成 那么为啥要装饰器呢?...

  • Day05

    一、装饰器进阶 多个装饰器同时装饰一个函数,执行顺序是由上往下执行被装饰函数执行之前的操作,再执行被装饰函数,最后...

  • Python装饰器(3)多装饰器装饰

    内容纯属个人理解,不对之处,欢迎指正。 多装饰器示例 运行结果: 通过现象看本质。我们注意到,程序开始执行后,装饰...

  • 装饰器

    装饰器就是在Python加载方法时,执行method=decorator(method),明白了这个自然可以理解装...

  • 装饰器4

    装饰器装饰类 使用类装饰器的时候,记得要返回被装饰的类调用的结果装饰器函数 再 init 之前执行 例子1:给类添...

  • Python中的Decorator装饰器

    Decorator 装饰器 理解decorator(装饰器)的关键, 在于理解在python中函数是第一公民, 并...

网友评论

      本文标题:理解装饰器的各种执行细节

      本文链接:https://www.haomeiwen.com/subject/ishkyxtx.html