這個主題考什麼
- 追蹤 __init__、self 和實例屬性在一次呼叫中的變化。
- 區分類級狀態和每個實例自己的狀態。
- 讀懂繼承和方法尋找,而不是靠猜。
常見錯誤
- 方法籤名裡忘記 self,或呼叫另一個方法時忘記 self。
- 把可變值放在類級別,卻以為每個實例都有獨立副本。
- 混淆類屬性和遮蔽它的實例屬性。
範例題
從完整題庫中挑出的 10 道代表題。先自己作答,再展開答案。
-
1. 小明的奶茶店類 class MilkTea 裡,self 參數代表什麼?
顯示答案
答案
B. 目前實例物件(這杯奶茶)解析: self 是方法被呼叫時那個實例本身,不是類。Python 會自動傳入,寫 c.describe() 時 self 就是 c,不需要手動傳。
-
2. 給類定義 __len__ 方法後, 該類的物件可以?
顯示答案
答案
A. 直接用 len() 獲取長度解析: 定義 __len__ 後,len(obj) 會呼叫它,物件因此能用在需要長度的場景。__str__、__add__ 也是同樣的協議機制。
-
3. 🧋 小明的奶茶店類,店名共用、每杯口味獨立,類變數的特點是?
顯示答案
答案
A. 所有實例共用解析: 類變數只在類上存一份,所有實例讀到同一個值;直到某個實例給同名屬性賦值,才會生成自己的實例屬性,實例賦值才分家。
-
4. 建立實例時先執行哪個方法?
顯示答案
答案
A. __new__解析: __new__ 負責分配並回傳實例,之後 __init__ 才初始化這個實例。除了不可變型別,很少重寫 __new__。
-
5. 小明建立奶茶時自動呼叫的初始化方法名是 ___
顯示答案
答案
__init__解析: __init__ 由建立實例的機制自動呼叫,時機是新實例已經存在之後,所以它拿到的是 self;在 __init__ 裡賦值就建立實例屬性。
-
6. 哪個屬性暴露實例的屬性字典?
print(Cup().__dict__)顯示答案
答案
__dict__解析: __dict__ 是每個實例自己的命名空間,self.x 賦值就存在這裡。類屬性掛在類上,不在這個字典裡。
-
7. 自動生成 __init__ 和 __repr__ 的裝飾器是什麼?
顯示答案
答案
dataclass解析: @dataclass 根據帶註解的欄位生成 __init__、__repr__ 和 __eq__,所以它寫在 class 語句上方。
-
8. 改實例的同名屬性,會影響類屬性嗎?
class Cup: size = "M" c = Cup() c.size = "L" print(Cup.size, c.size)顯示答案
答案
M L解析: c.size = "L" 寫進實例自己的字典,Cup.size 沒變。類屬性繼續給其他實例提供預設值,所以列印出來是 M L。
-
9. `append([], [])` 回傳什麼?
def append(list1, list2): return concat([list1, list2]) def concat(lists): return [element for list in lists for element in list] def filter(function, list): return [item for item in list if function(item)] def length(list): return sum(1 for _ in list) def map(function, list): return [function(element) for element in list] def foldl(function, list, initial): if len(list) == 0: return initial else: return foldl(function, list[1:], function(initial, list[0])) def foldr(function, list, initial): if len(list) == 0: return initial else: return function(foldr(function, list[1:], initial), list[0]) def reverse(list): return list[::-1] print(append([], []))顯示答案
答案
[]解析: append 把兩個參數放進串列交給 concat,concat 展開一層;兩個空串列展開後仍是 []。
-
10. `reverse(['xyz', 4.0, 'cat', 1])` 回傳什麼?
def append(list1, list2): return concat([list1, list2]) def concat(lists): return [element for list in lists for element in list] def filter(function, list): return [item for item in list if function(item)] def length(list): return sum(1 for _ in list) def map(function, list): return [function(element) for element in list] def foldl(function, list, initial): if len(list) == 0: return initial else: return foldl(function, list[1:], function(initial, list[0])) def foldr(function, list, initial): if len(list) == 0: return initial else: return function(foldr(function, list[1:], initial), list[0]) def reverse(list): return list[::-1] print(reverse(['xyz', 4.0, 'cat', 1]))顯示答案
答案
[1, 'cat', 4.0, 'xyz']解析: 負步長切片從末尾往前複製元素;reverse 不比較型別,字串和浮點數只換順序、值不變,也不會排序,順序與型別無關。
常見問題
self 是什麼?
self 是傳給實例方法的實例。呼叫 obj.method() 時,Python 會自動傳入它。
什麼時候用類而不是字典?
當行為應該和資料放在一起,或需要清晰介面和驗證時用類。只是簡單記錄、沒有行為時,字典就夠了。
繼續保持練習節奏。
完整題庫會在這個瀏覽器裡記住進度,支援依主題篩選,並包含每日一題和錯題重練。