--- title: Python Class(上) image: https://i.imgur.com/hfBqYPs.jpg tags: cpsd --- ## Class 類別 ```python class ClassName: psss ``` - 自定義物件 - 把數個資料或函數綁在一起 ### 多用class - 包裝你的程式 - 好讀 - 好懂 - 減少重複性高的程式碼 - 物件導向程式設計(有興趣可以google這個) - 看起來比較專業 :heavy_check_mark: ### 怎麼用 ```python class Computer: pass cp_1 = Computer() cp_1.cpu = 'R5-4500' cp_1.size = 16 cp_1.price = 35000 cp_2 = Computer() cp_2.cpu = 'M1' cp_2.size = 14 cp_2.price = 40000 # 印印看 print(cp_1) print(cp_1.cpu) print(cp_2.price) ``` - class 底下的資料 (cpu, size, price) 稱為屬性 ### magic methods 魔術方法 - class 中以雙底線包住的函數稱為 magic methods,通常是系統定義的名字 - 知道自己在寫甚麼的時候才這樣命名 ```python class Computer: def __init__(self, cpu, size, price): self.cpu = cpu self.size = size self.price = price ``` - 除了 `__init__`,其他魔術方法還有 `__add__`、`__sub__`、`__str__`... - 用來告訴 python 這個類別執行某些動作(初始化、四則運算、型態轉換...)時要怎麼處理 - `__init__`定義初始化(建構物件)時的動作 - `__init__`中的參數名稱不一定要跟屬性一樣,但不一樣會導致混亂且沒必要不一樣 ```python class Car: def __init__(self, x, y, z): self.name = x self.price = y self.color = z # 合法但極不推薦 ``` ```python cp_3 = Computer('Ryzen Threadripper 3970X', 32, 120000) ``` - 將參數 cpu 存入屬性 cp_3.cpu - 將參數 size 存入屬性 cp_3.size - 將參數 price 存入屬性 cp_3.price ### method 方法 - class 底下的函數稱為 method ```python class Computer: def discount(self): self.price *= 0.9 def size_cm(self): return self.size*2.54 def rename_cpu(self, newName): self.cpu = newName print(cp_3.cpu) # output: Ryzen Threadripper 3970X cp_3.rename_cpu('Intel Xeon E-2314') print(cp_3.cpu) # output: Intel Xeon E-2314 print(cp_3.size, 'inch =', cp_3.size_cm(), 'cm') # output: 32 inch = 81.28 cm print(cp_3.price) # output: 120000 cp_3.discount() print(cp_3.price) # output: 108000.0 ``` - 不想噴錯或發生奇怪的事情的話第一個參數一定要放 self ### Instance 實體 class 只是設計圖(樣板) 實際存在的是 instance ,依照 class 將東西做出來 class 的好處就是大量製造多個資料和功能的實體 :::success ### 小練習0 小明不小心把墨水打翻在他的 code 上,好樣的小明 ```python class Student: def __init__(self, name, math, english, chinese): 墨墨墨墨墨 墨墨墨墨墨 墨墨墨墨墨 墨墨墨墨墨 def average(墨墨墨墨墨): 墨墨墨墨墨 # 回傳平均成績 def is_pass(墨墨墨墨墨): 墨墨墨墨墨 # 若且唯若每科成績都不低於 60 則回傳 True me = Student('Sun', 101, 6, 60) print(me.average()) print(me.is_pass()) ``` ::: <!--解答 class Student: def __init__(self, name, math, english, chinese): self.name = name self.math = math self.english = english self.chinese = chinese def average(self): return sum((self.math, self.english, self.chinese)) / 3 # 回傳三科的平均值 def is_pass(self): return min((self.math, self.english, self.chinese)) >= 60 # 每一科都不低於60分就回傳true boss = Student('Sophia', 1000, 100, 100) print(boss.average()) print(boss.is_pass()) --> :::success ### 小練習1 挑戰題 ```python from math import gcd class Rational: def __init__(self, p, q): t = gcd(p, q) p, q = p // t, q // t self.p = p self.q = q def __str__(self): return '{}/{}'.format(self.p, self.q) def __add__(self, a): # print('{} + {}'.format(self, a)) nu = self.p * a.q + a.p * self.q di = self.q * a.q com = gcd(nu, di) return Rational(nu // com, di // com) # Your part here!! def __sub__(self, a): # x - y # print('{} - {}'.format(self, a)) pass def __mul__(self, a): # x * y # print('{} * {}'.format(self, a)) pass def __truediv__(self, a): # x / y # print('{} / {}'.format(self, a)) pass def __eq__(self, a): # x == y # print('{} == {}'.format(self, a)) pass if __name__ == '__main__': r = Rational(1, 4) s = Rational(3, 8) t = Rational(2, 8) print(r + s) print(r - s) print(r * s) print(r / s) print(r == s) print(r == t) ``` ::: <!--解答 from math import gcd class Rational: def __init__(self, p, q): t = gcd(p, q) p, q = p // t, q // t self.p = p self.q = q def __str__(self): return '{}/{}'.format(self.p, self.q) def __add__(self, a): # print('{} + {}'.format(self, a)) nu = self.p * a.q + a.p * self.q di = self.q * a.q com = gcd(nu, di) return Rational(nu // com, di // com) # Your part here!! def __sub__(self, a): # x - y # print('{} - {}'.format(self, a)) nu = self.p * a.q - a.p * self.q di = self.q * a.q return Rational(nu, di) def __mul__(self, a): # x * y # print('{} * {}'.format(self, a)) nu = self.p * a.p di = self.q * a.q return Rational(nu, di) def __truediv__(self, a): # x / y # print('{} * {}'.format(self, a)) nu = self.p * a.q di = self.q * a.p return Rational(nu, di) def __eq__(self, a): # x == y # print('{} == {}'.format(self, a)) return self.p == a.p and self.q == a.q if __name__ == '__main__': r = Rational(1, 4) s = Rational(3, 8) t = Rational(2, 8) print(r + s) # Ratinal.__add__(r, s) print(r - s) print(r * s) print(r / s) print(r == s) print(r == t) --> ### 可以開始打專案一了~