您好,登錄后才能下訂單哦!
學習面向對象的第一步,就是創(chuàng)建一個類。因為類是面向對象的基石。Python類和其他編程語言(Java、C#等)的類差不多,也需要使用class關鍵字。下面通過一個實際的例子來看一下Python類是如何創(chuàng)建的。
本例會創(chuàng)建一個類,以及利用這個類創(chuàng)建兩個對象,并調(diào)用其中的方法。
# 創(chuàng)建一個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))
# 創(chuàng)建Person對象
person1 = Person()
# 創(chuàng)建Person對象
person2 = Person()
# 調(diào)用person1對象的setName方法
person1.setName("Bill Gates")
# 調(diào)用person2對象的name屬性
person2.name = "Bill Clinton"
# 調(diào)用person1對象的getName方法
print(person1.getName())
# 調(diào)用person1對象的greet方法
person1.greet()
# 調(diào)用person2對象的屬性
print(person2.name)
# 調(diào)用person2對象的greet方法,另外一種調(diào)用方法的方式
Person.greet(person2)
程序運行結果如下圖所示。
從上面的代碼我們可以了解到Python類的如下知識點。
如果使用集成開發(fā)環(huán)境,如PyDev、PyCharm,那么代碼編輯器也會對面向對象有很好的支持,例如,當在對象變量后輸入一個點(.)后,IDE會為我們列出該對象中所有可以調(diào)用的資源,包括方法和屬性,如下圖所示。
Python類默認情況下,所有的方法都可以被外部訪問。不過像很多其他編程語言,如Java、C#等,都提供了private關鍵字將方法私有化,也就是說只有類的內(nèi)部方法才能訪問私有化的方法,通過正常的方式是無法訪問對象的私有化方法的(除非使用反射技術,這就另當別論了)。不過在Python類中并沒有提供private或類似的關鍵字將方法私有化,但可以曲線救國。
在Python類的方法名前面加雙下劃線(__)可以讓該方法在外部不可訪問。
class Person:
# method1方法在類的外部可以訪問
def method1(self):
print("method1")
# __method2方法在類的外部不可訪問
def __method2(self):
print("method2")
p = Person()
p.method1()
p.__method2() # 拋出異常
如果執(zhí)行上面的代碼,會拋出如下圖所示的異常信息,原因是調(diào)用了私有化方法method2。
其實“method2”方法也不是絕對不可訪問。Python編譯器在編譯Python源代碼時并沒有將“method2”方法真正私有化,而是一旦遇到方法名以雙下劃線(__)開頭的方法,就會將方法名改成“ClassNamemethodName”的形式。其中ClassName表示該方法所在的類名,“methodName”表示方法名。ClassName前面要加上但單下劃線()前綴。
對于上面的代碼,Python編譯器會將“method2”方法更名為“_Personmethod2”,所以在類的外部調(diào)用“method2”方法會拋出異常。拋出異常的原因并不是“method2”方法被私有化了,而是Python編譯器把“method2”的名稱改為“_Personmethod2”了。當我們了解了這些背后的原理,就可以通過調(diào)用“_Personmethod2”方法來執(zhí)行“method2”方法。
p = Person()
p._Person__method2() # 正常調(diào)用“__method2”方法
本例會創(chuàng)建一個MyClass類,并定義兩個公共的方法(getName和setName)和一個私有的方法(outName)。然后創(chuàng)建了MyClass類的實例,并調(diào)用了這些方法。為了證明Python編譯器在編譯MyClass類時做了手腳,本例還使用了inspect模塊中的getmembers函數(shù)獲取MyClass類中所有的成員方法,并輸出方法名。很顯然,“outName”被改成了“_MyClass__outName”。
class MyClass:
# 公共方法
def getName(self):
return self.name
# 公共方法
def setName(self, name):
self.name = name
# 在類的內(nèi)部可以直接調(diào)用私有方法
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("------------")
# 調(diào)用setName方法
myClass.setName("Bill")
# 調(diào)用getName方法
print(myClass.getName())
# 調(diào)用“__outName”方法,這里調(diào)用了改完名后的方法,所以可以正常執(zhí)行
myClass._MyClass__outName()
# 拋出異常,因為“__outName”方法在MyClass類中并不存在
print(myClass.__outName())
程序運行結果如下圖所示。
從getmembers函數(shù)列出的MyClass類方法的名字可以看出,“_MyClassoutName”被綁定到了“outName”方法上,我們可以將“_MyClassoutName”看做是“outName”的一個別名,一旦為某個方法起了別名,那么原來的名字在類外部就不可用了。MyClass類中的getName方法和setName方法的別名和原始方法名相同,所以在外部可以直接調(diào)用getName和setName方法。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。