1. 程式人生 > >Python:筆記(3)——面向對象編程

Python:筆記(3)——面向對象編程

擁有 存儲 內部 關鍵字參數 定義 有變 屬性綁定 ace 設置

Python:筆記(3)——面向對象編程

類型與對象

術語

  程序中存儲的所有數據都是對象。每個對象都有一個身份、一個類別和一個值。

如:a=42,就是用值42創建了一個整數對象。

  大多數對象都擁有大量特點的屬性和方法。

  • 屬性就是與對象相關的值。
  • 方法就是被調用時將在對象上執行某些操作的函數。
  • 使用 . 運算符可以訪問屬性和方法。

Python中對象的一些說明

  1. 檢查對象類型最佳的方式是利用內置函數 isinstance(object,type)
  2. 所有對象都有引用計數,當一個對象的引用計數歸零時,他將會被垃圾收集機制處理掉。
  3. 對於像字符串和數字這樣的不可變對象,a=b,實際上是創建了一個新的副本。
  4. 淺復制將創建一個新對象,但是它裏面包含的值是對原始對象中包含的項的引用
  5. 深復制將創建一個新對象,並且遞歸地復制它所包含的所有對象。可以使用copy.deepcopy()函數完成該工作。
  6. 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

【幾點說明】:

  1. 註意到__init__方法的第一個參數永遠是self,表示創建的實例本身,因此,在__init__方法內部,就可以把各種屬性綁定到self,因為self就指向創建的實例本身
  2. 和普通的函數相比,在類中定義的函數只有一點不同,就是第一個參數永遠是實例變量self,並且,調用時,不用傳遞該參數。除此之外,類的方法和普通函數沒有什麽區別,所以,你仍然可以用默認參數、可變參數、關鍵字參數和命名關鍵字參數。
  3. 和靜態語言不同,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 #這是不允許的

【幾點說明】

  1. 在Python中,變量名類似__xxx__的,也就是以雙下劃線開頭,並且以雙下劃線結尾的,是特殊變量,特殊變量是可以直接訪問的,不是private變量,所以,不能用__name____score__這樣的變量名。
  2. 有些時候,你會看到以一個下劃線開頭的實例變量名,比如_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)——面向對象編程