python 中的decorator

python 中decorator的做用就是一個包裝的做用,所謂包裝指在執行真正的函數以前或者以後,咱們能夠有一些額外的發揮餘地。python

decorator形式以下web

 

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的字節碼code


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>) blog

                     //將表明realfun的PyCodeObject壓入value stack
      21 MAKE_FUNCTION 0
                      //根據棧頂表明realfun的PyCodeObject生成 PyFunctionObject,返回以後,源碼

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

                     //調用func_replace(realfun) ,返回call_real_func 這個PyFunctionObject壓入class

                    //value stack
                    //到此至關於 dec('abc')(realfun)
        27 STORE_NAME 1 (realfun) //替換掉 realfun
                    //到此至關於realfun=dec('abc')(realfun)object

 

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_VALUEfile

 

 

分析以後能夠知道@的做用就是在調用dec以後又添加了一個調用,並且這個調用的格式是固定的是func( realfun)這種。

因此

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

 

這個的實際做用是realfun=dec('abc')(realfun)。中間有一個產生PyFunctionObject,而且隱藏了調用dec返回PyFunctionObject的過程

 

另外有一種沒有參數的decorator,他們省去了調用dec這一步,效果至關於realfun=dec(realfun);

相關文章
相關標籤/搜索