類別 (class) 用來設計自己需要的物件 (object) ,也就是說類別是物件的藍圖。 Python 中設計類別使用關鍵字 (keyword) class ,裡頭可定義類別的類別屬性 (class attribute) 、實體屬性 (instance attribute) 與方法 (method) 等等
先舉一例示範如何定義類別
001 | class Demo: |
002 | def set_att(self, a, b): |
003 | self.a = a |
004 | self.b = b |
005 | |
006 | def do_something(self): |
007 | return self.a + self.b |
008 | |
009 | d = Demo() |
010 | d.set_att(11, 22) |
011 | print(d.do_something()) |
012 | |
013 | # 檔名: class_demo.py |
014 | # 作者: Kaiching Chang |
015 | # 時間: July, 2014 |
class 後面空一格,然後接類別的識別字,此例為 Demo ,最後接一個冒號
001 | class Demo: |
下面用縮排的方式定義兩個方法,方法定義使用函數 (function) 定義相同的關鍵字 def
001 | class Demo: |
002 | def set_att(self, a, b): |
003 | self.a = a |
004 | self.b = b |
005 | |
006 | def do_something(self): |
007 | return self.a + self.b |
方法其實跟函數很多地方是一樣的,簡單說,方法可以看作是物件專屬的函數,這裡兩個方法 set_att() 與 do_something() 都有一個參數 (parameter) 名為 self
002 | def set_att(self, a, b): |
我們用橄欖色標記 self ,主要因為這是個識別字 (identifier) ,代表物件本身自己,當然可以自己取第一個參數的名稱,不過習慣上都用 self 。
標準模組庫 (standard library) 中的識別字同樣用橄欖色標記。
set_att() 有兩個參數 a 與 b ,這兩個參數用來設定實體屬性 self.a 與 self.b
003 | self.a = a |
004 | self.b = b |
物件又稱為實體 (instance) ,因為這是從類別所創造出來的。由於 self 在方法定義中表示物件本身,因此凡是方法中用 self. 接識別字都是實體屬性,這是物件的屬性值。
下面建立 Demo 物件,然後呼叫 set_att() 與 do_something()
009 | d = Demo() |
010 | d.set_att(11, 22) |
011 | print(d.do_something()) |
建立物件類似呼叫函數,指派運算子後面為類別名稱加上小括號,此例執行結果如下
參數也可以有預設值,這就在參數列 (parameter list) 直接指派數值即可,另舉一例如下
001 | class Demo: |
002 | def set_att(self, a=22, b=33): |
003 | self.a = a |
004 | self.b = b |
005 | |
006 | def do_something(self): |
007 | return self.a + self.b |
008 | |
009 | d = Demo() |
010 | d.set_att() |
011 | print(d.do_something()) |
012 | |
013 | # 檔名: class_demo2.py |
014 | # 作者: Kaiching Chang |
015 | # 時間: July, 2014 |
這裡將 set_att() 的兩個參數都設定初值,因此呼叫時沒有給參數,執行結果如下
下例示範在類別中設置類別屬性及類別方法 (class method)
001 | class Demo: |
002 | a = 11 |
003 | b = 22 |
004 | |
005 | @classmethod |
006 | def do_something(cls): |
007 | cls.a += 1 |
008 | cls.b += 1 |
009 | return cls.a + cls.b |
010 | |
011 | print(Demo.do_something()) |
012 | |
013 | # 檔名: class_demo3.py |
014 | # 作者: Kaiching Chang |
015 | # 時間: July, 2014 |
類別屬性是放在 class 關鍵字底下,通常會直接設定初值
001 | class Demo: |
002 | a = 11 |
003 | b = 22 |
類別方法則要用裝飾器 (decorator) @classmethod 標示,我們用橘色的語法高亮度標記這個裝飾器
005 | @classmethod |
006 | def do_something(cls): |
007 | cls.a += 1 |
008 | cls.b += 1 |
009 | return cls.a + cls.b |
同樣的,類別方法的第一個參數習慣上採 cls ,藉由 cls 可存取類別屬性,此例的 do_something() 除了將類別屬性遞增外,也回傳兩個類別的相加值。
呼叫類別方法則是直接以類別名稱呼叫
011 | print(Demo.do_something()) |
執行結果如下
Python 的屬性都預設為公開,就是可以在類別以外的地方存取,接下來我們介紹如何限制屬性只能在類別中存取,也就是把屬性封裝 (encapsulate) 在類別中。
中英文術語對照
物件 | object |
關鍵字 | keyword |
類別屬性 | class attribute |
實體屬性 | instance attribute |
方法 | method |
函數 | function |
參數 | parameter |
識別字 | identifier |
標準模組庫 | standard library |
實體 | instance |
參數列 | parameter list |
類別方法 | class method |
裝飾器 | decorator |
封裝 | encapsulate |
重點整理
- 類別是物件設計的藍圖,每一個類別都可定義屬性及方法。
- 方法如同函數,專屬於類別。實體屬性屬於由類別建立的物件,類別屬性則屬於類別,須由類別名稱調用。
- self 為預設的的參數名稱,表示物件實體。
- __init__() 是類別定義中特殊的方法,用來建立物件。
問題與討論
- 方法跟函數有什麼異同?
- 為什麼要有類別屬性?類別屬性跟實體屬性有什麼不同?
- 如果不寫 self ,那可以用其他的字代替嗎?
練習
- 寫一個程式 exercise0901.py ,裡頭設計一個類別 IntegerDemo , 利用 set_value() 方法設定實體屬性 value ,另外定義 add() 方法, add() 需要一個參數 p ,其內容為 value 加上 p ,執行部分先將 vlaue 設定為 25 ,然後再呼叫 add() 並以 24 當參數。
- 承上題,另寫一個程式 exercise0902.py ,改成由使用者輸入兩個整數。
- 承上題,另寫一個程式 exercise0903.py ,加入 subtract() 方法, subtract() 是將 value 減去參數值,最後結果儲存在 value 。
- 承上題,另寫一個程式 exercise0904.py ,繼續擴充 IntegerDemo ,加入乘法的方法。
- 承上題,另寫一個程式 exercise0905.py ,繼續擴充 IntegerDemo ,加入除法的方法。
- 寫一個程式 exercise0906.py ,仿照 IntegerDemo ,將方法改成計算階層值,結果儲存在 value 。
- 寫一個程式 exercise0907.py ,仿照 IntegerDemo ,將方法改成計算費氏數列,結果儲存在 value 。
the end
1 則留言:
張貼留言