python 多重装饰器执行顺序

版权声明:可以胡乱转载。 https://blog.csdn.net/hunyxv/article/details/60125569
#file_1.py
#--coding:utf-8 --
#代码来自http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

class mylocker:
    def __init__(self):
        print("mylocker.__init__() called.")

    @staticmethod
    def acquire():
        print("mylocker.acquire() called.")

    @staticmethod
    def unlock():
        print("  mylocker.unlock() called.")


class lockerex(mylocker):
    @staticmethod
    def acquire():
        print("lockerex.acquire() called.")

    @staticmethod
    def unlock():
        print("  lockerex.unlock() called.")


def lockhelper(cls):
    '''cls 必须实现acquire和release静态方法'''

    def _deco(func):
        def __deco(*args, **kwargs):
            print("before %s called." % func.__name__)
            cls.acquire()
            try:
                return func(*args, **kwargs)
            finally:
                cls.unlock()

        return __deco

    return _deco
#file_2.py

from file_1 import *


class example:
    @lockhelper(mylocker)
    def myfunc(self):
        print(" myfunc() called.")

    @lockhelper(mylocker)
    @lockhelper(lockerex)
    def myfunc2(self, a, b):
        print(" myfunc2() called.")
        return a + b


if __name__ == "__main__":
    a = example()
    a.myfunc()
    print(a.myfunc())
    print("------------------------------------")
    print(a.myfunc2(1, 2))
    print("------------------------------------")
    print(a.myfunc2(3, 4))

运行结果:

before myfunc called.
mylocker.acquire() called.
 myfunc() called.
  mylocker.unlock() called.
before myfunc called.
mylocker.acquire() called.
 myfunc() called.
  mylocker.unlock() called.
None
------------------------------------
before __deco called.
mylocker.acquire() called.
before myfunc2 called.
lockerex.acquire() called.
 myfunc2() called.
  lockerex.unlock() called.
  mylocker.unlock() called.
3
------------------------------------
before __deco called.
mylocker.acquire() called.
before myfunc2 called.
lockerex.acquire() called.
 myfunc2() called.
  lockerex.unlock() called.
  mylocker.unlock() called.
7

看了好久都没有看懂多重装饰器执行顺序………….

看了几篇博客文章才明白

首先,装饰器是按装饰器自下而上执行顺序执行

@lockhelper(mylocker)
@lockhelper(lockerex)

即先执行装饰器@lockhelper(lockerex)再执行@lockhelper(mylocker)

  1. 首先经过装饰器@lockhelper(lockerex)装饰后myfunc2()
    就等于装饰器函数中_deco()函数的返回值__deco() ,但此时__deco()不执行。

  2. 然后再被装饰器@lockhelper(mylocker)装饰,注意此时传递进去的函数是__deco(),所以此时输出before __deco called.

  3. 继续往下执行函数func()即__deco(),输出:before myfunc2 called. 继续
    cls.acquire()lockerex.acquire() 输出:lockerex.acquire()
    called.
  4. 再往后执行func() 这次func() 是被修饰的函数 myfunc2() 输出myfunc2() called.
  5. 再往下依次输出lockerex.unlock() called. mylocker.unlock()
    called.
    ,最后输出返回值 a + b。

参考:Python 装饰器执行顺序迷思

展开阅读全文

没有更多推荐了,返回首页