標籤:底線 fine 子類 不同的 attribute ini 對象的使用方法 實現 部分
類和對象
Pyhon中的類和對象與C++中的類和對象有著很大的差別,但是他們都是為了對一個對象的屬性和方法進行封裝,下面就具體討論Pyhon的類和對象的使用方法。
一,建構函式
class Foo: def __init__(num): self.num = num
f=Foo(1)
當使用類初始化對象時自動調用__init__()方法。
二,類屬性和執行個體屬性
類屬性可以通過執行個體對象或者類本身去調用
class Foo: name = "isFoo" def __init__(self): passf = Fooprint(f.name) #isFooprint(Foo.name)#isFoo
執行個體屬性可以通過建構函式來綁定,也可以直接綁定
class Foo: def __init__(self,name): self.name = namef = Foo("Jack")f.age = 18
print(f.name) #Jack#執行個體屬性可以通過屬性字典來查看print(f.__dict__) #{‘name‘: ‘Jack‘, ‘age‘: 18}
注意事項:
1,類屬性只能通過類調用去修改
2,若用執行個體區修改類屬性,將直接設定一個與類屬性同名的執行個體屬性
三,繼承
Python3全部是新式類,即類無論是否繼承object類,都預設繼承它。
class Animal: def eat(self): print("%s eating sth" % self.name)class Cat(Animal): def __init__(self, name): self.name = namec = Cat("miaomiao") c.eat() # miaomaio eating sth
子類若沒有建構函式,則使用父類的建構函式,若有,即有兩種方式來調用父類的建構函式
class Animal: def __init__(self,age): self.age=age def eat(self): print("%s eating sth" % self.name) class Cat(Animal): def __init__(self, name,age): # Animal.__init__(self,age) #first super().__init__(age) #second self.name = name
抽象類別
四,組合與重用
當幾個類有著共同的屬性時,我們可以將共同的部分抽象出來當做父類,而組合則是一種所有關係,如學校與老師,班級與學生。
class Student: def __init__(self,name,age): self.name=name self.age=ageclass class_grade: def __init__(self): self.li=[] def put(self,name,age): self.li.append(Student(name, age))c=class_grade()c.put("Jack",18)print(c.li[0].name,c.li[0].age) #Jack 18
五,封裝
封裝具有兩個特點:
將屬性和方法封裝在一個對象中,隱藏細節,僅提供介面;
具有存取控制;
第一個特點在前文已經闡述完了,我們來看Python類中的存取控制。
在Python中並沒有真正的限制類的外部或者是子類對類內部資料的訪問,而是一種約定,一種隱藏不直接暴露。
通過雙底線來隱藏
class Foo: __N=2 def __init__(self): self.__name="Jack" def func(self): print(self.__N) #0 print(self.__name) #Jack 類的內部可以直接通過名字訪問f=Foo()f.func()# print(self.__name) name #‘self‘ is not defined# print(f.__N) #‘Foo‘ object has no attribute ‘__N‘print(f._Foo__N) #可以通過_類名__變數名 訪問 執行個體屬性和函數屬性同理
這種變形需要注意的問題是:
1.這種機制也並沒有真正意義上限制我們從外部直接存取屬性,知道了類名和屬性名稱就可以拼出名字:_類名__屬性,然後就可以訪問了,如a._A__N,即這種操作並不是嚴格 意義上的限制外部存取,
僅僅只是一種文法意義上的變形,主要用來限制外部的直接存取。
2.變形的過程只在類的定義時發生一次,在定義後的賦值操作,不會變形
那麼我們可以用以下方法來給外部提供一個方法,使類外面對私人變數友好訪問
property(特性)
class Foo: __N = 2 def __init__(self): self.__name = "Jack" @property #訪問 def name(self): return self.__name @name.setter #設定值 def name(self, value): if not isinstance(value, str): print("請輸入字串類型") else: self.__name = value @name.deleter #刪除 def name(self): del self.__namef = Foo()
print(f.name) #像是調用屬性,實則調用方法,也符合實際
f.name="Bob"
del f.name
通過實現不同的函數就能實現不同的存取控制
六,多態
我們先回顧一下C++中的多態:父類指標(引用)指向(引用)子類或者父類對象時,會根據實際對象的類型來調用不同的方法。而在python中,由雩都是動態資料類型,賦值的時候就是初始化,因此多態更偏向一種代碼邏輯而不是文法。
class demo1: def display(self): print("這是demo1")class demo2: def display(self): print("這是demo2")class demo3: def display(self): print("這是demo3")def func(obj): obj.display()if __name__ == ‘__main__‘: d1 = demo1() d2 = demo2() d3 = demo3() # ---調用同一個函數的不同表現形態-- func(d1) # 這是demo1 func(d2) # 這是demo2 func(d3) # 這是demo3
Python初探第三篇-物件導向