在解釋@函數裝飾器之前,先說一下,類中的類方法和靜態方法。
在Python中完全支持定義類方法、靜態方法。這兩種方法很相似,Python它們都使用類來調用(ps:用對象調用也可以)。
區別在於:Python會自動綁定類方法的第一個參數,類方法的第一個參數會自動綁定到類本身;但對於靜態方法則不會自動綁定。
類方法用@classmethod修飾,靜態方法用@staticmethod修飾,如下:
1 #coding=utf-8 2 class Person: 3 @classmethod 4 def eat(cls): 5 print("類方法eat:",cls) 6 7 @staticmethod 8 def sleep(p): 9 print("靜態方法sleep:",p) 10 11 12 Person.eat() 13 Person.sleep("info") 14 15 p = Person() 16 17 p.eat() 18 p.sleep('info')
控制台打印如下:
解釋:eat方法因為是@classmethod修飾所以它是類方法,所以第12行調用時,不用傳入任何參數,即可以調用,因為它會自動綁定類本身到第一個參數。
sleep方法因為是@staticmethod修飾所以它是靜態方法,所以在第13行調用時,需要傳入參數。再看17、18行,可以得出結論:不管是用類或者對象調用靜態方法,Python都不會對靜態方法的第一個參數進行自動綁定。
上面的@classmethod 和 @staticmethod 其實就是函數裝飾器,其中classmethod和staticmethod為Python中內置的函數。
使用@符號引用已有函數后,可用於修飾其他函數。
例如@函數A 裝飾 函數B ,實際完成的步驟為:
1.將被裝飾的函數B作為參數傳給函數A
2.將函數B替換為第1步的返回值。
舉個例子:
1 def funA(fn): 2 """參數為一個函數對象""" 3 print('A') 4 fn() #執行傳入的fn函數 5 return 'tizer' 6 7 ''' 8 下面的代碼相當於funA(funB) 9 funB將會被替換為該語句的返回值 10 由於funA返回tizer,因此funB就是tizer 11 ''' 12 @funA 13 def funB(): 14 print('B') 15 print(funB)
先看運行結果:
解釋:既然funB作為參數傳給了funA,那就是得先執行funA中的代碼,所以執行了print(‘A’),打印了A,然后執行第4行fn(),因為傳入的funB,funB中的代碼為print('B'),所以打印了B,然后funA 返回了一個字符串tizer,所以funB 等同於 tizer,第15行print(funB) 等同於 print('tizer'),所以打印了tizer。