方法 綁定方法和非綁定方法 綁定方法和非綁定方法在創建時沒有任何區別,同一方法,既可以為綁定方法,也可以為非綁定方法,一切不同都只在調用時的手法上有所區別。 綁定方法即該方法綁定類的一個實例上,必須將self作為第一個參數傳入,而這個過程是由Python自動完成。可以通過實例名.方法名(參數列表)來 ...
方法
綁定方法和非綁定方法
綁定方法和非綁定方法在創建時沒有任何區別,同一方法,既可以為綁定方法,也可以為非綁定方法,一切不同都只在調用時的手法上有所區別。
綁定方法即該方法綁定類的一個實例上,必須將self作為第一個參數傳入,而這個過程是由Python自動完成。可以通過實例名.方法名(參數列表)來調用。
非綁定方法因為不綁定到實例上,所以在引用時通過類來進行引用。該過程不是 Python 自動完成,如果忘記傳入實例,那麼直接調用是肯定會出問題的。所以要調用類的非綁定方法時應該顯示地提供一個實例作為第一個參數。使用類名.非綁定方法名(參數列表)
的形式來進行引用
1 >>> class Foo(object): 2 def bar(self): 3 print "normal class" 4 5 6 >>> f =Foo() 7 >>> f.bar() #實例方法調用,不用顯示的傳入第一個參數self. 8 normal class 9 >>> Foo.bar(f) #類名.方法名 必須傳入參數f 10 normal class 11 >>> Foo.bar 12 <unbound method Foo.bar> #非綁定方法的對象 13 >>> f.bar #綁定方法 14 <bound method Foo.bar of <__main__.Foo object at 0x0000000003370B00>> 15 >>> dir(Foo)#查看類的屬性的名稱 16 ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar'] 17 >>> Foo.__dict__ #特殊屬性__dict__,作用查看類的屬性,是字典形式,key是屬性的名稱,value相應屬性對象的數據值 18 dict_proxy({'__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__module__': '__main__', 'bar': <function bar at 0x0000000003FC5EB8>, '__doc__': None}) 19 >>> Foo.__dict__['bar'] #查看bar是一個函數對象 20 <function bar at 0x0000000003FC5EB8>
#desr.__get__(self,obj,type=None)
#get、set、 del有人稱為黑魔法,我們叫它描述器
21 >>> Foo.__dict__['bar'].__get__(None,Foo) #第一個參數self賦值為None,意思是沒有給定的實例,非綁定方法 22 <unbound method Foo.bar> #非綁定方法 23 >>> f.bar #綁定方法 24 <bound method Foo.bar of <__main__.Foo object at 0x0000000003370B00>> 25 >>> Foo.bar #非綁定方法 26 <unbound method Foo.bar> 27 >>> Foo.__dict__['bar'].__get__(f,Foo) #第一個參數self 給定一個實例,綁定方法 28 <bound method Foo.bar of <__main__.Foo object at 0x0000000003370B00>> 29 >>>
#小結:通過類來獲取方法的時候,得到的是非綁定方法對象;通過實例來獲取方法的時候,得到的是綁定方法對象
靜態方法和類方法
語法上面的區別:
- 靜態方法不需要傳入self參數,類成員方法需要傳入代表本類的cls參數;
- 靜態方法是無法訪問實例變數和類變數的,類成員方法無法訪問實例變數但是可以訪問類變數
使用的區別:
由於靜態方法無法訪問類屬性,實例屬性,相當於一個相對獨立的方法,跟類其實並沒有什麼關係。這樣說來,靜態方法就是在類的作用域里的函數而已。
類方法:實例方法類似,不過其第一個參數一般是 cls (約定俗成)而不是 self。但是,如果我們直接將 self 換成 cls 來創建類方法是不對的,因為實例方法的首個參數也是任意的,只是統一使用 self 。python的解釋器並沒有說看見第一個參數是 cls 就知道這個是類方法,它還是將其當作是實例方法來對待,所以我們需要通過內建函數: classmethod() 來創建類方法。
示例:類方法
1 #! /usr/bin/env python 2 #coding:utf-8 3 4 class Foo(object): 5 6 one = 0 7 8 def __init__(self): #初始化函數 9 Foo.one =Foo.one + 1 #類屬性+1 10 11 @classmethod #創建類方法 12 def get_class_attr(cls):#傳遞一個參數 13 return cls.one #參數對象的屬性one 14 15 16 if __name__ =="__main__": 17 f1 =Foo() 18 print "f1:",Foo.one 19 f2 =Foo() 20 print "f2:",Foo.one 21 22 print f1.get_class_attr() 23 print "f1.one:",f1.one 24 print Foo.get_class_attr() 25 26 print "*"*10 27 f1.one = 8 #實例one屬性 28 Foo.one = 9 #類的one屬性 29 print f1.one 30 print f1.get_class_attr() 31 print Foo.get_class_attr() 32 33 34 #output 35 #f1: 1 36 #f2: 2 37 #2 38 #f1.one: 2 39 #2 40 #********** 41 #8 42 #9 43 #9
#小結:類方法的定義其實就是在方法前面要寫上@classmethod,在定義方法時,跟一般方法一樣,參數採用cls,目的是通過cls把類這個對象傳入
靜態方法
靜態方法:就是類中的一個普通函數,它並沒有預設傳遞的參數,在創建靜態方法的時候,需要用到內置函數: staticmethod() 。
1 #! /usr/bin/env python 2 #coding:utf-8 3 4 T =1 5 6 class Foo(object): 7 8 def __init__(self,name): 9 self.name = name 10 11 @staticmethod 12 def check_t(): 13 T =1 14 return T 15 16 def get_name(self): 17 if self.check_t(): 18 return self.name 19 else: 20 return "no person" 21 22 if __name__ == "__main__": 23 24 f = Foo("cc") 25 name =f.get_name() 26 print name