Python:筆記(3)——面向對象編程
Python:筆記(3)——面向對象編程
類型與對象
術語
程序中存儲的所有數據都是對象。每個對象都有一個身份、一個類別和一個值。
如:a=42,就是用值42創建了一個整數對象。
大多數對象都擁有大量特點的屬性和方法。
- 屬性就是與對象相關的值。
- 方法就是被調用時將在對象上執行某些操作的函數。
- 使用 . 運算符可以訪問屬性和方法。
Python中對象的一些說明
- 檢查對象類型最佳的方式是利用內置函數 isinstance(object,type)
- 所有對象都有引用計數,當一個對象的引用計數歸零時,他將會被垃圾收集機制處理掉。
- 對於像字符串和數字這樣的不可變對象,a=b,實際上是創建了一個新的副本。
- 淺復制將創建一個新對象,但是它裏面包含的值是對原始對象中包含的項的引用。
- 深復制將創建一個新對象,並且遞歸地復制它所包含的所有對象。可以使用copy.deepcopy()函數完成該工作。
- Python中的所有對象都是第一類的,也就是說能夠命名的所有對象都可以當做數據處理。
演示淺層和深層復制
1 # 淺層復制 2 a=[1,2,[3,4]] 3 b=list(a) #創建a的一個淺復制 4 print(b is a) 5 b.append(100) 6 print(b) 7 print(a) 8 b[2][0]=-100 9 print(b) 10 print(a)
【結果】:
False
[1, 2, [3, 4], 100]
[1, 2, [3, 4]]
[1, 2, [-100, 4], 100]
[1, 2, [-100, 4]]
1 #深層復制 2 import copy 3 a=[1,2,[3,4]] 4 b=copy.deepcopy(a) 5 b[2][0] =-100 6 print(b) 7 print(a)
【結果】: [1, 2, [-100, 4]] [1, 2, [3, 4]]
類和面向對象編程
類的創建
1 對象初始化方法 2 class myClass(object): 3 def __init__(self,type): 4 self.type=type 5 def printInfo(self): 6 print(self.name,‘age is‘,self.age) 7 print(self.name,"age is",self.age, sep=‘,‘) 8 9 10 aClass = myClass(1) 11 # 給對象賦予屬性 12 aClass.name = ‘Bob‘ 13 aClass.age=19 15 # 查看對象屬性 16 aClass.name 17 aClass.age 18 aClass.type 19 # 調用對象方法 20 aClass.printInfo() 21 【輸出】 22 Bob age is 19 23 Bob,age is,19
【幾點說明】:
- 註意到
__init__
方法的第一個參數永遠是self
,表示創建的實例本身,因此,在__init__
方法內部,就可以把各種屬性綁定到self
,因為self
就指向創建的實例本身。 - 和普通的函數相比,在類中定義的函數只有一點不同,就是第一個參數永遠是實例變量
self
,並且,調用時,不用傳遞該參數。除此之外,類的方法和普通函數沒有什麽區別,所以,你仍然可以用默認參數、可變參數、關鍵字參數和命名關鍵字參數。 - 和靜態語言不同,Python允許對實例變量綁定任何數據,也就是說,對於兩個實例變量,雖然它們都是同一個類的不同實例,但擁有的變量名稱都可能不同。
訪問限制
說明:
如果要讓內部屬性不被外部訪問,可以把屬性的名稱前加上兩個下劃線_,在Python中,實例的變量名如果以 _ 開頭,就變成了一個私有變量(private),只有內部可以訪問。
1 class Student(object): 2 def __init__(self, name, score): 3 self.__name = name 4 self.__score = score 5 6 def print_score(self): 7 print(‘%s: %s‘ % (self.__name, self.__score)) 8 def getName(self): 9 print(self.__name)
【說明】
bob = Student(‘Bob‘,99)
bob.print_score()
bob.getName()
bob.__name #這是不允許的
【幾點說明】
- 在Python中,變量名類似
__xxx__
的,也就是以雙下劃線開頭,並且以雙下劃線結尾的,是特殊變量,特殊變量是可以直接訪問的,不是private變量,所以,不能用__name__
、__score__
這樣的變量名。 - 有些時候,你會看到以一個下劃線開頭的實例變量名,比如
_name
,這樣的實例變量外部是可以訪問的,但是,按照約定俗成的規定,當你看到這樣的變量時,意思就是,“雖然我可以被訪問,但是,請把我視為私有變量,不要隨意訪問”。
繼承和多態
動態語言的“鴨子類型”,它並不要求嚴格的繼承體系,一個對象只要“看起來像鴨子,走起路來像鴨子”,那它就可以被看做是鴨子。
Python允許使用多重繼承,於Python這樣的動態語言來說,則不一定需要傳入Animal類型。我們只需要保證傳入的對象有一個run()方法就可以了:
1 class Animal(object): 2 def run(self): 3 print(self.name) 4 def __init__(self,name): 5 self.name=name 6 class Dog(Animal): 7 pass 8 9 def test(animal): 10 animal.run() 11 12 dog = Dog("Animal") 13 test(dog)
獲取對象信息
1.如果要獲得一個對象的所有屬性和方法,可以使用dir()
函數,它返回一個包含字符串的list.
2.配合getattr()
、setattr()
以及hasattr()
,我們可以直接操作一個對象的狀態
3.總是優先使用isinstance()判斷類型,可以將指定類型及其子類“一網打盡”。
使用__slots__限制實例屬性
Python允許在定義class的時候,定義一個特殊的__slots__
變量,來限制該class實例能添加的屬性:
1 class Student(object): 2 __slots__ = (‘name‘, ‘age‘) # 用tuple定義允許綁定的屬性名稱 3 4 >>> s = Student() # 創建新的實例 5 >>> s.name = ‘Michael‘ # 綁定屬性‘name‘ 6 >>> s.age = 25 # 綁定屬性‘age‘ 7 >>> s.score = 99 # 綁定屬性‘score‘ 8 Traceback (most recent call last): 9 File "<stdin>", line 1, in <module> 10 AttributeError: ‘Student‘ object has no attribute ‘score‘
使用@property
1.裝飾器限制屬性取值:把一個getter方法變成屬性,只需要加上@property
就可以了,我們也可以添加setter方法
1 class Student(object): 2 @property 3 def score(self): 4 return self._score 5 @score.setter 6 def score(self, value): 7 if not isinstance(value, int): 8 raise ValueError(‘score must be an integer!‘) 9 if value < 0 or value > 100: 10 raise ValueError(‘score must between 0 ~ 100!‘) 11 self._score = value
2.設置只讀屬性:只定義getter方法,不定義setter方法就是一個只讀屬性
1 class Student(object): 2 3 @property 4 def birth(self): 5 return self._birth 6 7 @birth.setter 8 def birth(self, value): 9 self._birth = value 10 11 @property 12 def age(self): 13 return 2015 - self._birth
使用枚舉類
1.簡單創建枚舉類
1 from enum import Enum 2 3 Month = Enum(‘Month‘, (‘Jan‘, ‘Feb‘, ‘Mar‘, ‘Apr‘, ‘May‘, ‘Jun‘, ‘Jul‘, ‘Aug‘, ‘Sep‘, ‘Oct‘, ‘Nov‘, ‘Dec‘))
2.繼承Enum:@unique
裝飾器可以幫助我們檢查保證沒有重復值。
1 from enum import Enum, unique 2 3 @unique 4 class Weekday(Enum): 5 Sun = 0 # Sun的value被設定為0 6 Mon = 1 7 Tue = 2 8 Wed = 3 9 Thu = 4 10 Fri = 5 11 Sat = 6
Python:筆記(3)——面向對象編程