您的位置:首页 > 编程语言 > Python开发

python 中的decorator

2016-06-14 13:13 375 查看
python 中decorator的作用就是一个包装的作用,所谓包装指在执行真正的函数之前或者之后,我们可以有一些额外的发挥余地。

decorator形式如下

def dec(arg1):
print("dec",arg1)
def func_replace(func):
print("func_replace",func)

def call_real_func(*args,**kwargs):
print("call_real_func")
func(*args,**kwargs)
return call_real_func
return func_replace

@dec("abc")
def realfun(arg):
print("realfun",arg)

realfun("123")


  "@"的作用,我们通过这份代码产生的python bytecode来弄清楚@的作用

F:\pyweb>python -m dis decorator.py
源码行号 字节码偏移 字节码 注释
1      0 LOAD_CONST 0 (<code object dec at 00BE74A0, file "decorator.py", line 1>)
      3 MAKE_FUNCTION 0
      6 STORE_NAME 0 (dec)
                  //到此为止是def dec(): 产生 代表dec PyFunction的字节码

12      9 LOAD_NAME 0 (dec) //加载 dec 对应的PyFunctionObject
      12 LOAD_CONST 1 ('abc') //压入 'abc'到value-stack
      15 CALL_FUNCTION 1   //调用函数,就是dec('abc'),然后建dec 返回的 func_replace压到 value stack
                    //到此相当于 dec('abc')
      18 LOAD_CONST 2 (<code object realfun at 00BE74E8, file "decorator.py", line 12>)

                     //将代表realfun的PyCodeObject压入value stack
      21 MAKE_FUNCTION 0
                     //根据栈顶代表realfun的PyCodeObject生成 PyFunctionObject,返回之后,

                    //value stack的值为:PyFunctionObject(func_replace),PyFunctionObject(realfun)
      24 CALL_FUNCTION 1

                     //调用func_replace(realfun) ,返回call_real_func 这个PyFunctionObject压入

                    //value stack
                    //到此相当于 dec('abc')(realfun)
       27 STORE_NAME 1 (realfun) //替换掉 realfun
                    //到此相当于realfun=dec('abc')(realfun)

17      30 LOAD_NAME 1 (realfun)
      33 LOAD_CONST 3 ('123')
      36 CALL_FUNCTION 1
      39 POP_TOP
      40 LOAD_CONST 4 (None)
      43 RETURN_VALUE

分析之后可以知道@的作用就是在调用dec之后又添加了一个调用,而且这个调用的格式是固定的是func( realfun)这种。

所以

@dec("abc")
def realfun(arg):
  print("realfun",arg)

这个的实际作用是realfun=dec('abc')(realfun)。中间有一个产生PyFunctionObject,并且隐藏了调用dec返回PyFunctionObject的过程

另外有一种没有参数的decorator,他们省去了调用dec这一步,效果相当于realfun=dec(realfun);

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: