跳转至

第 1 周周测(闭卷,40 分钟,20 题)

写在纸上或新建一个空白文件里作答;不开 REPL、不开 AI。答案见 exercises/solutions/week1/quiz_week1_answers.md。评分:每题 1 分,≥16 分通过;错题进下周一的回忆清单。

一、预测输出(10 题)

  1. python g = (x * x for x in range(4)) print(sum(g), sum(g))
  2. python def gen(): yield 1 yield 2 return "done" it = gen() print(next(it), list(it)) 追问:"done" 去哪了?
  3. python fs = [lambda: i for i in range(3)] gs = [lambda i=i: i for i in range(3)] print([f() for f in fs], [f() for f in gs])
  4. python import functools def deco(fn): @functools.wraps(fn) def w(*a, **k): return fn(*a, **k) * 2 return w @deco def add(a, b): """加法""" return a + b print(add(1, 2), add.__name__, add.__doc__) 追问:去掉 @functools.wraps(fn) 后两个值分别变成什么?
  5. python from itertools import batched, groupby print(list(batched("abcdefg", 3))) print([(k, list(v)) for k, v in groupby("aabba")])
  6. python from dataclasses import dataclass, field @dataclass class P: x: int tags: list[str] = field(default_factory=list) a, b = P(1), P(1) print(a == b, a is b, a.tags is b.tags)
  7. python class V: def __init__(self, *xs): self.xs = list(xs) def __len__(self): return len(self.xs) def __getitem__(self, i): return self.xs[i] v = V(3, 1, 2) print(len(v), 2 in v, list(reversed(v)), bool(V()))
  8. python class A: def hi(self): return "A" class B(A): def hi(self): return "B" + super().hi() class C(A): def hi(self): return "C" + super().hi() class D(B, C): pass print(D().hi(), [k.__name__ for k in D.__mro__])
  9. python def f(): try: return "try" finally: print("finally") print(f())
  10. python from contextlib import contextmanager @contextmanager def cm(log): log.append("enter") try: yield "val" finally: log.append("exit") log = [] with cm(log) as v: log.append(v) print(log)

二、找 bug(5 题,说出问题与修法)

  1. python def add_tag(tag, tags=[]): tags.append(tag) return tags
  2. python class Money: def __init__(self, v): self.v = v def __eq__(self, o): return self.v == o.v seen = {Money(1)}
  3. python def timer(fn): def wrapper(*a, **k): return fn(*a, **k) return wrapper (功能上能跑,但用了它的函数在 help() 和调试器里会发生什么?)
  4. python from itertools import groupby data = ["apple", "banana", "avocado"] groups = {k: list(v) for k, v in groupby(data, key=lambda s: s[0])} 期望 {"a": ["apple", "avocado"], "b": ["banana"]}
  5. python try: risky() except Exception: pass

三、写函数(5 题)

  1. 写生成器 evens(limit):产出 0, 2, 4, ... 直到 < limit;再写 take(n, it)itertools.islice 取前 n 个。
  2. 写装饰器 retry(times):被装饰函数抛异常时最多重试 times 次,最后一次仍失败则原样抛出;用 functools.wraps
  3. 写上下文管理器 cd(path)(用 @contextmanager):进入时切换到 path,退出时无论是否出错都切回原目录。
  4. @dataclass(frozen=True, order=True) Version(major: int, minor: int),并让 str(Version(1, 2)) == "1.2";说明 frozen=True 带来的两个效果。
  5. class Shape(ABC) 含抽象方法 area()class Square(Shape);再写 class HasArea(Protocol),让一个不继承 ShapeCircle 也能传给 total_area(items: Iterable[HasArea]) -> float。说明 ABC 与 Protocol 的区别一句话。