# Python ## 實作前導課程:class & object Part I ### 2022 / 4 / 15 ### Tony --- ## 其實你已經看過class了?! ---- 先前的課程教過`type()`函式, 可以回傳指定物件的型態 但你有認真看那個"型態"是甚麼嗎? :::spoiler Example ```python= x = 10 name = "Tony" def Say_Hi(): print("Hi") print(type(x)) #<class 'int'> print(type(name)) #<class 'str'> print(type(Say_Hi)) #<class 'function'> ``` ::: ---- 他們的資料型態前面都有一個class,代表 **int, str等等的資料型態其實都是不同的class(類別)** 而這些值、變數則都是那些Class的物件(object) ---- 有時候我們會需要更複雜,但是Python沒有內建的資料結構 這個時候就要自己寫一個class出來 ```python= class Dog class Students class Course ... ``` --- ## 寫寫看簡單的class ---- 我們可以寫一個簡單的class來玩玩看 ```python= class Dog: def __init__(self, name , age , color): pass def speak(self): print('Bark') ``` ---- \_\_init__函式:有這個class的物件被創造的時候會自動執行的函式 class裡面的函式,多數時候第一個引數都會是<font color = 'orange'>`self`</font>,代表執行該函式的物件 ```python= def __init__(self, name, age, color): self.name = name self.age = age self.color = color ``` ---- 宣告物件並跟函式互動 ```python= Sam = Dog("Sam", 16, "Black") Sam.speak() # "Bark" ``` --- ## class之間的互動 ---- 有的時候你會需要不同的複雜資料結構彼此幫忙 以"課程"跟"學生"為例 :::spoiler 模板 ```python= # Multiple classes interaction class Student: def __init__(self, name, age, grade): self.name = name self.age = age self.grade = grade # 0 ~ 100 def get_grade(self): return self.grade class Course: def __init__(self, name, max_students): pass def add_student(self, student): pass def get_average_grade(self): pass if __name__ == '__main__': s1 = Student('Tim', 16, 90) s2 = Student('Tony', 17, 85) s3 = Student('Max', 20, 65) course = Course('Physics', 2) course.add_student(s1) course.add_student(s2) print(course.students) print(course.students[0].name) print(course.get_average_grade()) ``` ::: ---- \_\_init__: 設定課程名稱、學生上限、參加的學生(用一個list儲存) ```python= def __init__(self, name, max_students): self.name = name self.max_students = max_students self.students = [] # We can create an attribute that is not one of the parameters. ``` ---- add_student(): 還沒滿人時,把要參加的學生加進課程裡面 ```python= def add_student(self, student): if len(self.students) < self.max_students: self.students.append(student) return True return False ``` ---- get_average_grade(): 算出學生們的平均分數 ```python= def get_average_grade(self): value = 0 for student in self.students: value += student.get_grade() return value / len(self.students) ``` ---- 完整Code ```python= # Multiple classes interaction class Student: def __init__(self, name, age, grade): self.name = name self.age = age self.grade = grade # 0 ~ 100 def get_grade(self): return self.grade class Course: def __init__(self, name, max_students): self.name = name self.max_students = max_students self.students = [] # We can create an attribute that is not one of the parameters. def add_student(self, student): if len(self.students) < self.max_students: self.students.append(student) return True return False def get_average_grade(self): value = 0 for student in self.students: value += student.get_grade() return value / len(self.students) ``` --- ## 繼承 Inheritance ---- 想像你想要寫$n$個class,分別代表$n$種課程 它們都有名稱、短介紹、開課人數 其中有$k$種課程要收費,$m$種課程只開放半年 想想看要怎麼寫? ---- 你可以一個一個像這樣: ```python= class AI_Crash_Course: def __init__(self, intro, max_student, date, tuition_fee): self.intro = intro self.max_student = max_student self.date = date self.tuition_fee = tuition_fee def get_grade(self): ... #以下忽略N行 ``` 但是這樣太慢了,而且太多行了,好複雜 有沒有更方便的寫法? ---- 繼承:讓一個子類別(Chind_clsss)可以使用母類別(Parent_class)所有的函式,但不用全部寫出來 並且接受子類別自己重新調整、更新母類別寫過的函式 ---- 舉例:我要寫兩個class分別代表狗跟貓 他們都有名字、年紀、顏色,也都會叫 所以我先寫一個寵物class讓他們繼承 ```python= class Pet: def __init__(self, name, age, color): self.name = name self.age = age self.color = color ``` ---- 繼承的寫法:把Parent_class寫在Child_class的名稱後面,用小括號包起來 ```python= class Dog(Pet): pass class Cat(Dog): pass ``` ---- 使用Parent_class的函式:super() `super()`代表現在這個class的Parent_class ```python= class Dog(Pet): def __init__(self, name, age, color): super().__init__(name, age, color) def speak(self): print(f'I am {self.name} and I am {self.age} years old and I am {self.color}') class Cat(Pet): def __init__(self, name, age, color): super().__init__(name, age, color) def speak(self): print(f'I am {self.name} and I am {self.age} years old and I am {self.color}') ``` --- ## 為什麼要學class? ---- 優點: * 方便處理"同一個東西有很多屬性"的專案 * 可以分類函式、讓程式語言變得更一目了然 ```python= dog1_name = "Sam" dog1_age = 16 ... # 如果需要一堆狗,你就會要打一堆有關的變數,出錯機率就會提高 dogs_name = ["Sam", "Apollo", ...] dogs_age = [16, 16, ...] #這種方法在刪除跟新增資料時會格外麻煩,還要特別花時間找到對的index ```
{"metaMigratedAt":"2023-06-16T23:09:41.107Z","metaMigratedFrom":"YAML","title":"Python實作前導課程:class & object Part I","breaks":true,"slideOptions":"{\"transition\":\"slide\",\"theme\":null}","contributors":"[{\"id\":\"4f731eff-9d88-41f4-af56-2e3e02f20cfc\",\"add\":7683,\"del\":2529}]"}
    221 views