iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Software Development

闖進Python異世界系列 第 13

[Day 13] 闖進Python異世界 - Class 方法 - 實戰開模 Part 2/2

  • 分享至 

  • xImage
  •  

接續上一篇的開模實戰!

完成了建構子的實作,也代表著我們定義了大多數的學生屬性,包含姓名、體重、成績、興趣:

class Student:
    def __init__(self, name, weight, gpa, *hobbies):
        self.name = name
        self.weight = weight
        self.gpa = gpa
        self.hobby = []
        for hobby in hobbies:
          self.hobby.append(hobby)

為什麼說是大部分的屬性呢?
因為在接下來的method中,我們也可以再定義一些屬性。
所有的 self.xxx 都稱為該類別屬性

接著我們就準備讓學生動起來了!


方法(Method

類別的行為被定義在「方法」中!
什麼是方法呢?簡單來說,是類別中的函式。

方法的優點有哪些?

  1. 方法可以「直接」使用該類別的屬性(self.xxx)
  2. 方法可以為類別新增屬性
  3. 增加可讀性

如果將方法皆改為函式,程式架構會相對亂許多。
因為當程式規模增加,你不會清楚當初這個函式的功用是哪一個類別的方法。

我們先把我們構想中學生的行為列出來:

  1. 吃飯 eat(food, foodWeight)
    • foodWeight 單位為「公克」
    • 學生吃完飯後,體重會是原體重加上食物重量
  2. 運動 exercise(sport, duration)
    • duration 單位為「分鐘」
    • 每運動 2 小時,體重變輕1公斤
  3. 讀書 study(subject, duration)
    • duration 單位為「分鐘」
    • 每讀書 2 小時,gpa 增加 0.1

實戰

我們要實作的是「方法」,所以我們定義的時候要多給一個 self 的參數,代表類別本身。

class Student:
    '''
        constructor is here
    '''
    def eat(self, food, foodWeight):
        print(f"{self.name} eats {food} today.")
        self.weight += foodWeight * 0.001
    def exercise(self, sport, duration):
        print(f"{self.name} plays {sport} for {duration} minutes today.")
        self.weight -= duration / 60
    def study(self, subject, duration):
        print(f"{self.name} studies {subject} for {duration / 60} hours today.")
        self.gpa += duration / 120 * 0.1

測試之前,先宣告一個物件吧!

John = Student('John', 80, 3.9, 'sleep', 'sing')

測試方法的可行性。

John.eat('apple', 100) # John eats apple today.
John.exercise('badminton', 70) # John plays badminton for 70 minutes today.
John.study('Math', 90) # John studies Math for 1.5 hours today.

由結果可知,上述的程式碼都有達到我們的期望。


用方法建造新屬性

如果我們在執行方法時,需要新的屬性,我們可以直接宣告。

直接從範例來看看吧!假設我們需要一個判斷學生是否有進步的類別方法:

  1. 先檢查物件是否有 self.bestScore 這個屬性
  2. 如果沒有,我們就新增這個屬性
  3. 如果有,我們就判斷是否有進步
class Student:
    '''
        之前定義的建構子、方法置於此處
    '''
    def isBetter(self, score):
        if 'bestScore' not in vars(self):
            self.bestScore = score
            print('Good start')
            return True
        elif score > self.bestScore:
            self.bestScore = score
            print('Good job')
            return True
        elif score == self.bestScore:
            print('Keep going')
            return False
        elif score < self.bestScore:
            print('Need Improve')
            return False

練習一下:
以下的程式碼為什麼有錯誤?
AttributeError: 'Student' object has no attribute 'bestScore'

class Student:
    def __init__(self, name, weight, gpa):
        print(vars(self))
        self.name = name
        self.weight = weight
        self.gpa = gpa
    def isBetter(self, score):
        if 'bestScore' not in vars(self):
            self.bestScore = score
            print('Good start')
            return True
        elif score > self.bestScore:
            self.bestScore = score
            print('Good job')
            return True
        elif score == self.bestScore:
            print('Keep going')
            return False
        elif score < self.bestScore:
            print('Need Improve')
            return False
John = Student('John', 67, 3.8)
print(f"John's name = {John.name}")
print(f"John's weight = {John.weight}")
print(f"John's gpa = {John.gpa}")
print(f"John's best score = {John.bestScore}")

因為物件還沒 self.bestScore 這個屬性,因此會出錯。
我們必須先執行過 isBetter(self, score) 這個函式,物件才會有這個屬性。


簡單的開模實作就介紹到這裡啦!
大致整理一些重點:

  • 類別 = 屬性 + 方法
  • 物件由建構子創造
  • 建構子和所有方法的第一個參數必定是 self
  • vars() 可以得到物件的所有屬性

關於類別設計的知識還很多,如:存取限制、繼承等,有興趣可以自行翻閱資料。

接下來,我們要實際使用 class 了喔!


上一篇
[Day 12] 闖進Python異世界 - Class 屬性 - 實戰開模 Part 1/2
下一篇
[Day 14] 闖進Python異世界 - Linked List
系列文
闖進Python異世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言