这个主题考什么
- 追踪 __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 会自动传入它。
什么时候用类而不是字典?
当行为应该和数据放在一起,或需要清晰接口和校验时用类。只是简单记录、没有行为时,字典就够了。
继续保持练习节奏。
完整题库会在这个浏览器里记住进度,支持按主题筛选,并包含每日一题和错题重练。