--- ###### tags: `資訊之芽` --- # Class 講師:洪郁凱 --- Class類別 大綱 - 基本概念 - 屬性/隱藏 - 方法 - 繼承/聚合 ---- 大家好,我不是老糕 今天 我們來講 ---- *Class* ---- 有一派人說 Python世界裡的東西 都是由物件組成 ---- 所以只要精通物件,那麼你就在Python中無敵了 ---- 好啦可能不會(X) ---- ## 基本概念 - python裡面的資料都是物件 - class像是物件的規格書 - 自訂的一種資料結構 (Optional) - 利用類別 可以做出很多類似的物件(instance) ---- ## 基本概念 一個class可以生很多物件! ---- ## 基本概念 神奇的指令 檢查obj是不是用class做出來的 ```python= isinstance(obj,class) #回傳obj物件是否由class所縣立的 ``` ---- ## 基本概念 ```python= isinstance([1,2,3],list) ``` list是一個class!? ---- ## 基本概念 ```python= isinstance(5,int) ``` int也是一個class!!?? ---- ## 基本概念 那能不能直接查某物件是屬於哪個class的? ---- ## 基本概念 想知道他是什麼class來的 可以用type() ```python= type(3) # <class 'int'> ``` 出現"class" 也有了解釋 ---- ### 不太基本但沒關係 ```python= class Itaewon(): pass kim = Itaewon() print(type(kim)) # <class '__main__.Itaewon'> ``` kim屬於Itaewon(梨泰院) Class ![](https://i.imgur.com/jVVXeJx.png =300x) ---- ## 基本概念 基本語法 注意class的命名! ```python= class Name(): #宣告 神秘括號 pass object = Name() #建立物件 ``` Reminder: Class的名字首字通常為大寫 ---- ## 小節整理 - class vs 物件 - 查找物件所屬class - 宣告class ![](https://i.imgur.com/kViGy5F.png) [ref](https://zh.wikipedia.org/wiki/小傑·富力士) --- ## 屬性 物件裡面可以裝載的資料的地方 ---- ## 屬性 ```python= class Food(): pass bread = Food() bread.price = 50 #從外面加入屬性 ``` ---- ## 屬性 ```python= class Food(): def __init__(self): # 要加一個位置參數,代表新建立的物件 self.price = 50 # 透過初始化函式設定屬性 bread = Food() print(bread.price) #取值方法 ``` ---- ## 屬性 可能會讓你聯想到Dict? ```python= bread = dict() bread["price"] = 50 print(bread["price"]) #給Key 回傳Value ``` ---- ## self??? 第一個self是何方神聖? ```python class Food(): def __init__(): #故意不加self # self.price = 50 pass # __init__() takes 0 positional arguments but 1 was given ``` ---- ## self??? 第一個self是何方神聖? ```python class Food(): def __init__(): #故意不加self # self.price = 50 pass # __init__() takes 0 positional arguments but 1 was given ``` - _\_init__是製作物件時會被呼叫的函式,不必回傳東西 - 會給你即將出爐的物件 當作函式的第一個參數 ---- ## self??? 第一個self是何方神聖? ```python class Food(): def __init__(s): # 來看看第一個傳入的東西到底是啥 print(s) print(type(s)) print(id(s)) bread = Food() print(id(bread)) ``` ---- ## self??? 第一個self是何方神聖? ```python class Food(): def __init__(s): # 來看看第一個傳入的東西到底是啥 print(s) print(type(s)) print(id(s)) bread = Food() print(id(bread)) ``` - 透過查看id,可以知道__init__吃的第一個參數就是物件自己 - 請注意class Food()/bread = Food(),兩者括號裡面放的東西天差地遠 ---- ## 屬性 ```python= class Food(): def __init__(self,p): # 第二個位置參數才會是food括號中的第一個參數 self.price = p # 透過初始化函式設定屬性 bread = Food(39) print(bread.price) #取值方法 ``` ---- ## 屬性 如何刪除呢 ```python= class Food(): def __init__(self,p): #加入屬性的方法 self.price = p bread = Food(39) del bread.price print(bread.price) # 會壞掉 ``` ---- ## 屬性 一個簡單的範例 ```python= class Food(): def __init__(self,pri,siz,pop): self.price = pri self.size = siz self.popularity = pop cupcake = Food(39,"M",100) ``` ---- ## 整理 - __init\_\_ 函式參數 呼叫時機 - 物件的屬性加入/刪除 ---- ## QA Time 其他延伸: - getter/setter - private attribute - syntatic sugar ---- ## 小練習 ``` 寫一個class名為Drink 並生成兩個物件 有store price size flavor屬性 分別為"Starbucks" 180 "L" "抹茶奶霜星冰樂" 及 "麻古茶坊" 50 "M" "椰果奶茶" 之後練習一下把price刪除 改用point(分別為400,100) ``` ---- ## 好康大放送 ```python= class Car(): def __init__(self,price): self.price = price def drive(self): print("AMG開大的") bmw = Car(100) class Mini_Car(Car): def drive(self): print("開小車") mini_benz = Mini_Car(130) bmw.price # 100 mini_benz.price # 130 ``` --- ## 方法 物件裡面能放資料 那能不能放函式? ---- ## 方法 recall ```python= str1 = "This is an example" str1.count(" ") # 3 str2 = "A" str2.isalpha() # True [177,63,20,9,28].sort() ``` ---- ## 方法 規定怎麼去取用不同物件裡的內容 - 實例方法 Instance Method 針對物件 - 類別方法 Class Method 針對整個類別 - 靜態方法 Static Method ---- ## 宣告方法 ```python= class Food(): def eat(): #在裡面宣告 print('yummy') ``` ---- ## 宣告方法 ```python= def eat(): #在裡面宣告 print('yummy') class Food(): pass Food.eat = eat ``` ---- ## 宣告方法 ```python= class Food(): pass Food.eat = lambda : print('yummy') #從外部加入 # 宣告方法的方法(X) ``` optional:lambda 函式 ---- ## 宣告方法 方法內跟主程式內取值的作法一樣 ```python= class Food(): sold = 23 def count(): print(Food.sold,'packs of food has been sold') ``` ---- ## 實例方法 因為是針對各個物件的 實例方法需要傳入物件 ```python= def __init__(self): ``` ---- ## 實例方法 例如剛剛的初始化函式 ```python= class Food(): def __init__(self): self.price = 50 ``` ---- ## 實例方法 傳遞參數 ```python= class Food(): def set_price(self,in_price): #還記得self嗎 self.price = in_price a = Food() a.set_price(20) ``` ---- ## 實例方法 初始化函數傳遞參數的範例 ```python= class Food(): def __init__(self,pri,siz,pop): self.price = pri self.size = siz self.popularity = pop cupcake = Food(39,"M",100) ``` --- ## 類別方法 class method 只影響這個類別 以及這個類別之後建立的物件 ```python= class Pinky(): flavor = 3 # 類別屬性 @classmethod def cm(cls): print(f"{cls} has {cls.flavor} flavors.") strawberry = Pinky() strawberry.cm() Pinky.cm() ``` ---- ## 類別方法 可以用這個方式計算生出物件數量 ```python= class Food(): ind = 0 def __init__(self): self.ind = Food.ind Food.ind += 1 @classmethod def num_of_food(cls): print(f'有{cls.ind}個食物物件') Food.num_of_food() ``` ---- ## 類別方法 可以用這個方式計算生出物件數量 ```python= class Food(): ind = 0 def __init__(self): self.ind = Food.ind Food.ind += 1 @classmethod def num_of_food(cls): print(f'有{cls.ind}個食物物件') Food.num_of_food() ``` \@classmethod 是一種語法糖 --- ## 靜態方法 static method 不傳入實例 也不傳入類別 ```python= class Food(): @staticmethod def promote(): print('全面特價!') Food.promote() ``` ---- ## 方法整理 | X | 實例方法 | 類別方法 | 靜態方法 | | -------- | ---------- | ------------ | ------------- | | 對象 | 物件 | 類別 | None | | 參數 | func(self) | func(cls) | func() | | 呼叫 | obj.func() | cls.func() | cls.func() | ---- ## QA Time 在class/物件之中放函式的過程還順利嗎? ---- ## 練習時間! ``` 寫一個class 名叫 Motor Motor有一個屬性叫GonDaoPrice(公道價) 81000 生出兩個物件 有屬性 brand, name, discount, cc_motor 分別為 "Honda", "CB150r", 5000, 150 及 "YAMAHA", "勁戰六", 12000, 150 其中有一個實例方法getPrice 輸出GonDaoPrice - discount ``` ---- ## 好康大放送 ```python= class NewPinky(): def __init__(self,f): self.flavor = f def __str__(self): return f'My flavor is {self.flavor}' p = NewPinky("Grape") print(p) # My flavor is Grape ``` ---- ## 好康大放送 ```python= a = str(1234) print(a) # "1234" ``` --- ## 魔術方法 長相,呼叫方式不一樣的函式 ```python= print(1+2) print('1'+'2') print([1,]+[2,]) ``` ---- ## 魔術方法 來試圖寫一個自己的數字class ```python= class num(): def __init__(self,inp): self.value = inp ``` ---- ## 魔術方法 呼叫方式不一樣 ```python= class num(): def __init__(self,inp): self.value = inp def __add__(self,other): print('歡迎來到魔術方法') return self.value + other.value a = num(2) b = num(3) print(a+b) ``` ---- ## 魔術方法 不同型別也能用! ```python= class num(): def __init__(self,inp): self.value = inp def __add__(self,other): print('歡迎來到魔術方法') return self.value + other.value class food(): def __init__(self,inp): self.value = inp a = num(2) b = food(3) print(a+b) ``` ---- ## 魔術方法 運算類 | 魔術方法 | 對應符號 | | ----------------- | -------- | | \_\_add__(a,b) | a+b | | \_\_sub__(a,b) | a-b | | \_\_mul__(a,b) | a\*b | | \_\_truediv__(a,b) | a/b | | \_\_floordiv__(a,b) | a//b | | \_\_pow__(a,b) | a\*\*b | | \_\_mod__(a,b) | a%b | ---- ## 魔術方法 比較類 | 魔術方法 | 對應符號 | | ----------- | -------- | | \_\_eq__(a,b) | a==b | | \_\_ne__(a,b) | a!=b | | \_\_lt__(a,b) | a<b | | \_\_gt__(a,b) | a>b | | \_\_le__(a,b) | a<=b | | \_\_ge__(a,b) | a>=b | ---- ## 魔術方法 其他 | 魔術方法 | 對應 | | -------- | -------- | | \_\_new__(cls,) | 新增物件用的 | | \_\_init__(self,) | 初始化物件用的 | | \_\_str__(self) | 被當成字串的時候用的 | | \_\_repr__(self) | 在互動模式下被呼叫的 | | \_\_del__(self) | 在解構物件用的 | | \_\_int__(self) | 被int()呼叫用的 | [其他魔術](https://www.tutorialsteacher.com/python/magic-methods-in-python) --- ## 多型 Duck Type 概念:寫不同類別方法時 讓不同類別的物件一起運算 ---- ## 多型 Duck Type > if it looks like a duck swims like a duck and quacks like a duck then it probably is a duck ---- ## 多型 Duck Type 範例 ```python= a = [1,2,3] b = '123' print(len(a),len(b)) print(a.count(1),b.count(1)) #型別不同 行為相同 ``` --- ## 還有好多沒講的 時間不夠 自己研究 - 繼承 - 裝飾器 - 線性加速器 - 本質主義的窠臼 - 克服外觀焦慮 - 金賽性傾向連續性理論 - 征服銀河系 ---- ## 作業 還沒選
{"metaMigratedAt":"2023-06-16T20:59:38.445Z","metaMigratedFrom":"Content","title":"Class","breaks":true,"contributors":"[{\"id\":\"9a14c697-53b2-4214-a12a-512e946e0176\",\"add\":14734,\"del\":5985}]"}
    493 views
   owned this note