學習面向對象的第一步,就是建立一個類。由於類是面向對象的基石。Python類和其餘編程語言(Java、C#等)的類差很少,也須要使用class關鍵字。下面經過一個實際的例子來看一下Python類是如何建立的。html
本例會建立一個類,以及利用這個類建立兩個對象,並調用其中的方法。編程
# 建立一個Person類 class Person: # 定義setName方法 def setName(self, name): self.name = name # 定義getName方法 def getName(self): return self.name # 定義greet方法 def greet(self): print("Hello, I'm {name}.".format(name = self.name)) # 建立Person對象 person1 = Person() # 建立Person對象 person2 = Person() # 調用person1對象的setName方法 person1.setName("Bill Gates") # 調用person2對象的name屬性 person2.name = "Bill Clinton" # 調用person1對象的getName方法 print(person1.getName()) # 調用person1對象的greet方法 person1.greet() # 調用person2對象的屬性 print(person2.name) # 調用person2對象的greet方法,另一種調用方法的方式 Person.greet(person2)
程序運行結果以下圖所示。編程語言
從上面的代碼咱們能夠了解到Python類的以下知識點。編輯器
若是使用集成開發環境,如PyDev、PyCharm,那麼代碼編輯器也會對面向對象有很好的支持,例如,當在對象變量後輸入一個點(.)後,IDE會爲咱們列出該對象中全部能夠調用的資源,包括方法和屬性,以下圖所示。ide
Python類默認狀況下,全部的方法均可以被外部訪問。不過像不少其餘編程語言,如Java、C#等,都提供了private關鍵字將方法私有化,也就是說只有類的內部方法才能訪問私有化的方法,經過正常的方式是沒法訪問對象的私有化方法的(除非使用反射技術,這就另當別論了)。不過在Python類中並無提供private或相似的關鍵字將方法私有化,但能夠曲線救國。函數
在Python類的方法名前面加雙下劃線(__)可讓該方法在外部不可訪問。學習
class Person: # method1方法在類的外部能夠訪問 def method1(self): print("method1") # __method2方法在類的外部不可訪問 def __method2(self): print("method2") p = Person() p.method1() p.__method2() # 拋出異常
若是執行上面的代碼,會拋出以下圖所示的異常信息,緣由是調用了私有化方法method2。3d
其實「method2」方法也不是絕對不可訪問。Python編譯器在編譯Python源代碼時並無將「method2」方法真正私有化,而是一旦遇到方法名以雙下劃線(__)開頭的方法,就會將方法名改爲「ClassNamemethodName」的形式。其中ClassName表示該方法所在的類名,「methodName」表示方法名。ClassName前面要加上但單下劃線()前綴。code
對於上面的代碼,Python編譯器會將「method2」方法改名爲「_Personmethod2」,因此在類的外部調用「method2」方法會拋出異常。拋出異常的緣由並非「method2」方法被私有化了,而是Python編譯器把「method2」的名稱改成「_Personmethod2」了。當咱們瞭解了這些背後的原理,就能夠經過調用「_Personmethod2」方法來執行「method2」方法。orm
p = Person() p._Person__method2() # 正常調用「__method2」方法
本例會建立一個MyClass類,並定義兩個公共的方法(getName和setName)和一個私有的方法(outName)。而後建立了MyClass類的實例,並調用了這些方法。爲了證實Python編譯器在編譯MyClass類時作了手腳,本例還使用了inspect模塊中的getmembers函數獲取MyClass類中全部的成員方法,並輸出方法名。很顯然,「outName」被改爲了「_MyClass__outName」。
class MyClass: # 公共方法 def getName(self): return self.name # 公共方法 def setName(self, name): self.name = name # 在類的內部能夠直接調用私有方法 self.__outName() # 私有方法 def __outName(self): print("Name = {}".format(self.name)) myClass = MyClass() # 導入inspect模塊 import inspect # 獲取MyClass類中全部的方法 methods = inspect.getmembers(myClass, predicate=inspect.ismethod) print(methods) # 輸出類方法的名稱 for method in methods: print(method[0]) print("------------") # 調用setName方法 myClass.setName("Bill") # 調用getName方法 print(myClass.getName()) # 調用「__outName」方法,這裏調用了改完名後的方法,因此能夠正常執行 myClass._MyClass__outName() # 拋出異常,由於「__outName」方法在MyClass類中並不存在 print(myClass.__outName())
程序運行結果以下圖所示。
從getmembers函數列出的MyClass類方法的名字能夠看出,「_MyClassoutName」被綁定到了「outName」方法上,咱們能夠將「_MyClassoutName」看作是「outName」的一個別名,一旦爲某個方法起了別名,那麼原來的名字在類外部就不可用了。MyClass類中的getName方法和setName方法的別名和原始方法名相同,因此在外部能夠直接調用getName和setName方法。