本節將是Python面向對象的最後一篇博文了,這節將記錄類的特殊方法、特殊成員方法、舊類和新類的不一樣,以及一些其餘知識。Go!html
Python有三種特殊方法:實例方法、靜態方法、類方法。若是你讀過一些源代碼,你必定疑惑過這些代碼:@staticmethod、@classmethod,前面見到的全部方法都是實例方法,實例方法的第一個參數爲實例自己(self),因爲實例方法通過前面幾節已經掌握,全部本節將會熟悉剩下的兩種特殊方法安全
以前在類中編寫的各類方法其實都是屬於實例方法,每個方法的第一個參數是實例自己(self),實例方法當然好用,可是在開發中,須要一些這樣的方法:與類有關,在使用時不須要引用類和實例,也就是不能訪問類變量和實例變量。這些方法一般用來做全局的配置方法,使代碼更加簡潔和安全。函數
在類中的方法的前面使用裝飾器: @staticmethod 便可,靜態方法已經和普通函數沒有太大區別,惟一的區別就是靜態方法要經過對象來訪問,看例:spa
1 class Teacher: 2 def __init__(self, name, gender): 3 self.name = name 4 self.gender = gender 5 6 def talk(self): 7 print('I am {}'.format(self.name)) 8 9 @staticmethod # 建立 is_man 靜態方法 10 def is_man(gender): 11 if gender == 'male': 12 return 1 13 return 0
經過上例能夠看到靜態方法的建立比較簡單,基本上已經和類無關了,按照普通的函數建立便可code
靜態方法與函數的區別就是調用方式不一樣,函數直接調用便可,可是靜態方法多多少少和類仍是有一些關係的,那就是調用時須要對象來調用:orm
zhangsan = Teacher('zhangsan', 'male') print(zhangsan.is_man('male')) # 運行結果: 1
注意:靜態方法沒法調用類變量和實例變量,這裏就不做演示了。htm
『防抄襲:讀者請忽略這段文字,文章做者是博客園的MinuteSheep』對象
可是靜態方法一般並不會在類外調用靜態方法,而是直接在類內做爲全局配置方法使用,例如:blog
1 class Teacher: 2 def __init__(self, name, gender): 3 self.name = name 4 self.gender = gender 5 6 def talk(self): 7 print('I am {}'.format(self.name)) 8 9 @staticmethod 10 def is_man(gender): 11 if gender == 'male': 12 return 1 13 return 0 14 15 def eat(self): 16 flag = self.is_man(self.gender) # 做爲全局配置使用 17 if flag: 18 print('I am man, I will eat 2 buns') 19 else: 20 print('I am woman, I will eat 1 bun') 21 22 23 zhangsan = Teacher('zhangsan', 'male') 24 25 zhangsan.eat()
# 運行結果: I am man, I will eat 2 buns
若是超類中有靜態方法時,子類繼承時會發生什麼呢?繼承
class Teacher(object): def __init__(self, name, gender): self.name = name self.gender = gender @staticmethod def is_man(gender): if gender == 'male': return 1 return 0 def eat(self): flag = self.is_man(self.gender) # 做爲全局配置使用 if flag: print('I am {}, I will eat 2 buns'.format(flag)) else: print('I am {}, I will eat 1 bun'.formar(flag)) class Chinese(Teacher): ''' 建立一個語文老師類, 繼承Teacher ''' def __init__(self, name, gender): super().__init__(name, gender) @staticmethod # 改寫超類的靜態方法 def is_man(gender): if gender == 'male': return 'man' return 'woman' zhangsan = Chinese('zhangsan', 'male') zhangsan.eat()
繼承後將超類靜態方法改寫,運行結果j將按照子類的靜態方法運行,結果以下:
# 運行結果: I am man, I will eat 2 buns # 而不是按照超類的靜態方法 # I am 1,I will eat 2 buns
類方法,顧名思義是一種直接做用於類的方法。類方法和實例方法的區別就在於:類方法只能訪問類變量,不能訪問實例變量。
在類中的方法前面使用裝飾器: @classmethod 便可,類方法和實例方法格式類似,類方法第一個參數必須是類自己(cls),看例:
class Teacher(object): food = 'bun' def __init__(self, name, gender): self.name = name self.gender = gender @classmethod # 建立類方法 eat def eat(cls): print(cls.food)
經過上面代碼能夠看到,類方法的第一個參數爲類自己,習慣上用cls表示,固然也能夠用其餘單詞表示(這一點與self相似)
類方法的調用與實例方法無異,看例:
zhangsan = Teacher('zhangsan', 'male') zhangsan.eat() # 運行結果: bun
注意:類方法只能調用類變量,不能調用實例變量,這裏就不做演示了
『防抄襲:讀者請忽略這段文字,文章做者是博客園的MinuteSheep』
類方法常常出如今源代碼中,一般用來爲類傳入新的參數。
什麼事特殊成員方法呢?其實你已經見過了,那就是相似__init__這樣 __方法__ 形式的方法
__init__ 「構造函數,當實例化類對象時,會自動調用該方法」
class Test: def __init__(self): print('實例化類對象後就會運行我') Test() # 運行結果: 實例化類對象後就會運行我
__del__ 「析構函數,當類對象在內存中被釋放時(也就是類對象運行完後),會自動調用該方法」
class Test: def __del__(self): print('類對象釋放後就會運行我') Test() # 運行結果: 類對象釋放後就會運行我
__call__ 「call方法,在類或者對象後加括號執行該方法」
class Test: def __call__(self): print('我是博客園MinuteSheep,神馬文庫抄襲個人博文,不要臉') Test()() # 或者 # obj = Test() # obj() # 運行結果: 我是博客園MinuteSheep,神馬文庫抄襲個人博文,不要臉
__dict__ 「dict方法,查看類或者對象的全部成員信息」
class Test:
x = 1000 y = 'MS' print(Test.__dict__) # 運行結果: {'__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Test' objects>, 'x': 1000, '__doc__': None, 'y': 'MS', '__dict__': <attribute '__dict__' of 'Test' objects>}
__doc__ 「doc方法,查看類的描述信息」
class Test: ''' 這裏是類的描述信息 ''' x = 1000 y = 'MS' print(Test.__doc__) # 運行結果: 這裏是類的描述信息
Python3中,只有新類,舊類以及被移除, class 類名: 和 class 類名(object): 都是新類;Python2中, class 類名: 是舊類, class 類名(object): 是新類
對舊類和新類瞭解一下便可
舊類:深度優先
新類:廣度優先
1 # 在Python2中 2 3 4 class A: 5 pass 6 7 8 class B(A): 9 pass 10 11 12 class C(B): 13 pass 14 15 16 class D(A, B, C): 17 pass 18 19 20 D()
在Python2中,上述代碼的調用順序爲:D->A->B->A->C->B->A
明顯是深度優先
1 # 在Python2中 2 3 4 class A(object): 5 pass 6 7 8 class B(A): 9 pass 10 11 12 class C(B): 13 pass 14 15 16 class D(A, B, C): 17 pass 18 19 20 D()
在Python2中,上訴代碼的調用順序爲:D->A->B->C->A->B->A->object
明顯是廣度優先
接觸類這麼久了,你必定發現了又的方法和成員沒有下劃線,有的方法和成員只有一條下劃線,有的方法和成員首尾各有兩條下劃線,這究竟是什麼含義呢?
無下劃線 foo:表示普通方法和成員
一條下劃線 _foo:表示被保護方法和成員,不能被 from xxx import _foo 導入
兩條下劃線 __foo:表示私有方法和成員,只運行類自己進行訪問
首尾各兩條下劃線 __foo__:表示特殊方法,通常由系統自定義
Python面向對象的知識到此結束,多加理解和聯繫才能真正掌握面向對象的知識,拜拜~