
Day1无Day2 1. 题目编写一个函数 divide(a, b)返回 a/b 的结果。 要求如果 b0捕获异常并返回 除数不能为0 测试print(divide(10, 0)) # 应输出 除数不能为0 import shutil def divide(a, b): try: return a / b except ZeroDivisionError: return 除数不能为零 print(divide(10, 0)) print(divide(10, 2)) 2 题目用户输入一个数字程序计算 100 除以该数字。 要求捕获以下异常 - 用户输入非数字 → ValueError - 用户输入0 → ZeroDivisionError - 其他异常 → Exception 测试分别输入 abc、0、5 观察结果 def catch(): try: num input(输入一个数字) val float(num) result 100 / val print(f100 / {val} {result}) except ZeroDivisionError: print(f除零异常) except ValueError: print(f非数字值异常) except Exception as e : print(f其他异常{e}) a catch() 3索引错误与键错误 题目有一个列表 [1,2,3] 和字典 {a:1, b:2} 要求让用户输入索引或键名分别访问列表和字典。 捕获 IndexError 和 KeyError提示用户输入无效。 a [1, 2, 3] b {a: 1, b: 2} def catch(): try: idx input(输入索引) key input(输入键名) #尝试访问 list_value a[int(idx)] dict_key b[key] print(list_value) print(dict_key) except IndexError: print(索引无效) except KeyError: print(键名无效) c catch() 4自定义异常类 题目设计一个 BankAccount 类包含 - 属性balance余额 - 方法withdraw(amount) 取款 要求 1. 自定义异常 InsufficientFundsError余额不足异常 2. 取款金额超过余额时抛出该异常并捕获处理 3. 取款金额为负数时抛出 ValueError class BankAccount: def __init__(self, balance): self.balance balance def withdraw(self, amount): if amount 0: raise ValueError(取款金额不能为负) if amount self.balance: raise InsufficientFundsError(self.balance,amount) self.balance - amount return self def __str__(self): return f余额: {self.balance} class InsufficientFundsError(Exception): def __init__(self, balance, amount): self.amount amount super().__init__(f余额不足当前余额 {balance}请求取款 {amount}) a BankAccount(100) try: a.withdraw(200) except InsufficientFundsError as e: print(e) except ValueError as e: print(e) try: a.withdraw(-10) except ValueError as e: print(e) a.withdraw(50) print(f最终: {a}) 5异常链与重新抛出 题目编写两个函数 - read_file(filename)读取文件内容可能抛出 FileNotFoundError - process_data(filename)调用 read_file将内容转为大写 要求 1. process_data 捕获 FileNotFoundError 后 抛出 RuntimeError(文件处理失败) 并保留原始异常信息 2. 使用 raise ... from ... 语法 练习题6finally 与资源清理 题目编写一个函数 copy_file(src, dst)复制文件内容。 要求 1. 使用 open() 打开两个文件 2. 无论是否发生异常都要确保两个文件被关闭 3. 使用 try-finally 实现不能用 with 语句 4. 捕获所有可能的异常并打印错误信息 def read_file(filename): with open(filename,r,encodingutf_8) as f: return f.read() def process_data(filename): try: content read_file(filename) return content.upper() except FileNotFoundError as e: raise RuntimeError(文件处理失败) from e try: result process_data(./test.txt) print(result) except RuntimeError as e: print(f捕获到异常: {e}) try: result process_data(./est.txt) print(result) except RuntimeError as e: print(f捕获到异常: {e}) finally 与资源清理 题目编写一个函数 copy_file(src, dst)复制文件内容。 要求 1. 使用 open() 打开两个文件 2. 无论是否发生异常都要确保两个文件被关闭 3. 使用 try-finally 实现不能用 with 语句 4. 捕获所有可能的异常并打印错误信息 def copy_file(src, dst): src_file None dst_file None try: src_file open(src,r,encodingutf_8) dst_file open(dst,w,encodingutf_8) data src_file.read() dst_file.write(data) print(f复制成功{src}-----{dst}) except Exception as e: print(f错误{e}) finally: if src_file: src_file.close() if dst_file: dst_file.close() print(清理成功) copy_file(test.txt, dest.txt) copy_file(est.txt, dest.txt) Day3# 选择题 1. 以下哪个选项正确地描述迭代器 A. 迭代器是一个可以直接用索引访问元素的对象 迭代器不支持索引 B. 迭代器实现了 __iter__() 和 __next__() 方法可以逐个返回元素 C. 迭代器只能遍历列表类型的数据 遍历任何可迭代对象 D. 迭代器可以随意向前和向后移动 单向 B 2 以下哪些对象是可迭代对象Iterable但不是迭代器Iterator A. iter([1, 2, 3]) B. [1, 2, 3] C. range(5) D. map(str, [1, 2]) map() 方法是 Python 内置的一个高阶函数用于对可迭代对象中的每一个元素应用指定的函数并返回一个包含结果的迭代器。 BC #判断是否是迭代器 from collections.abc import Iterator, Iterable # 列表可迭代但不是迭代器 lst [1, 2, 3] print(isinstance(lst, Iterable)) # True print(isinstance(lst, Iterator)) # False # iter() 后的列表是迭代器 it iter(lst) print(isinstance(it, Iterator)) # True # 字符串可迭代不是迭代器 s hello print(isinstance(s, Iterator)) # False # 生成器是迭代器 gen (x for x in range(3)) print(isinstance(gen, Iterator)) # True def is_iterator(obj): 判断是否是迭代器同时有 __iter__ 和 __next__ return hasattr(obj, __iter__) and hasattr(obj, __next__) # 测试 print(is_iterator([1, 2, 3])) # False没有 __next__ print(is_iterator(iter([1, 2, 3]))) # True print(is_iterator(abc)) # False print(is_iterator(map(str, [1, 2]))) # Truemap 返回迭代器 def check(obj): try: it iter(obj) # 能转迭代器 → 可迭代 if it is obj: # 迭代器的 iter() 返回自身 return 是迭代器 return 是可迭代对象但不是迭代器 except TypeError: return 不可迭代 # 测试 print(check([1, 2, 3])) # 是可迭代对象但不是迭代器 print(check(iter([1, 2, 3]))) # 是迭代器 print(check(123)) # 不可迭代 3 以下哪个选项正确地说明了 for 循环的工作机制 A. for 循环直接访问容器元素不涉及迭代器 B. for 循环调用容器的 __getitem__() 方法遍历 C. for 循环内部通过调用 iter(container) 获取迭代器然后反复调用 next() D. for 循环使用 C 语言层面的优化不需要迭代器 C 4 在迭代器中iter() 方法应该返回什么 A. 返回迭代器自身self B. 返回一个新的迭代器对象 C. 返回第一个元素 D. 返回 None A 5 当迭代器耗尽元素时应该抛出什么异常 A. ValueError B. IndexError C. StopIteration D. RuntimeError C 6 以下代码的输出结果是什么 lst [1, 2, 3] it iter(lst) print(next(it)) print(next(it)) print(next(it)) print(next(it)) A. 1, 2, 3, 抛出 StopIteration B. 1, 2, 3, None C. 1, 2, 3, 抛出 IndexError D. 1, 2, 3, 4 A 7 一个对象被判断为迭代器的条件是 A. 它有 __iter__() 方法 B. 它有 __next__() 方法 C. 它有 __iter__() 和 __next__() 方法 D. 它实现了序列协议 C 8 以下哪种情况会创建一个新的迭代器 A. 使用 iter(obj) 时 B. 使用 next(it) 时 C. 使用 len(obj) 时 D. 使用 type(obj) 时 A 9 以下关于迭代器的说法哪个是错误的 A. 迭代器是一次性的遍历完后不能重置 B. 一个可迭代对象可以创建多个独立的迭代器 C. 迭代器可以记住当前遍历的位置 D. 迭代器支持通过索引随机访问元素 D 10 下面哪个操作能判断一个对象是否为可迭代对象 A. callable(obj) B. isinstance(obj, Iterable) C. hasattr(obj, __next__) D. iter(obj) 不抛出异常 B D 1.题目不使用 for 循环仅使用 while 和 next() 手动遍历列表 [5, 10, 15, 20, 25] 要求 1. 获取列表的迭代器 2. 用 while 循环逐个打印所有元素 3. 正确处理 StopIteration 异常 data [5, 10, 15, 20, 25] i iter(data) while True: try: num next(i) except StopIteration: break print(num) 2. 题目将字符串 Python 转换为迭代器依次打印每个字符。 要求 1. 使用 iter() 获取迭代器 2. 使用 for 循环遍历理解 for 循环底层使用的就是迭代器 str Python it iter(str) for char in it: print(char) 3. 题目实现一个 StepIterator 类它可以按指定步长遍历列表。 要求 1. 初始化时接收一个列表和步长 step默认1 2. 实现 __iter__ 和 __next__ 方法 3. 每次 next() 返回当前位置的元素然后索引向后移动 step 步 4. 当索引超出范围时抛出 StopIteration 示例 it StepIterator([1, 2, 3, 4, 5, 6, 7, 8], step2) for num in it: print(num) # 输出1, 3, 5, 7 class StepIterator: def __init__(self, iterable, step1): self.iterable iterable self.step step self.index 0 def __iter__(self): return self def __next__(self): if self.index len(self.iterable): raise StopIteration value self.iterable[self.index] self.index self.step return value it StepIterator([1, 2, 3, 4, 5, 6, 7, 8], step2) for num in it: print(num) # 输出1, 3, 5, 7 4. 题目实现一个 FibonacciIterator 类生成斐波那契数列有限长度。 要求 1. 初始化时指定要生成的项数 n 2. 从 1, 1 开始或者 0, 1两种都可以 3. 实现 __iter__ 和 __next__ 方法 4. 当生成完 n 项后抛出 StopIteration 示例 fib FibonacciIterator(6) for num in fib: print(num) # 输出1, 1, 2, 3, 5, 8 class FibonacciIterator: def __init__(self, n): self.n n self.sum 0 self.a 1 #前项 self.b 1 #后项 def __iter__(self): return self def __next__(self): if self.sum self.n: raise StopIteration value self.a self.a,self.b self.b, self.a self.b self.sum 1 return value fib FibonacciIterator(6) for num in fib: print(num) # 输出1, 1, 2, 3, 5, 8 Day4 编写生成器函数 fibonacci(limit)生成斐波那契数列不超过 limit 的所有值。 然后用列表推导式生成前10个偶数的列表。 def fibonacci(limit): a, b 0, 1 while a limit: yield a a, b b, ab print(list(fibonacci(10))) fib_evens [x for x in fibonacci(10) if x % 2 0][:10] print(fib_evens) 编写一个函数 make_counter它返回一个内部函数每次调用内部函数时返回一个递增的数字 从1开始。要求使用 nonlocal 实现。 编写一个闭包 make_multiplier(n)它返回一个函数该函数将传入的数字乘以 n。 例如 times2 make_multiplier(2); times2(5) 返回 10。 1. 编写一个闭包 make_multiplier(n)它返回一个函数该函数将传入的数字乘以 n。例如 times2 make_multiplier(2); times2(5) 返回 10。 def make_multiplier(n): def multiplier(x): return x * n return multiplier times2 make_multiplier(2) print(times2(5)) 2. 练习2有一个外部函数它接收一个列表内部函数可以对列表进行追加或弹出操作。 闭包中要保存列表的修改状态请实现。 def make_list(x): lit x class Method: #将方法挂载到实例上 def add(self, y): lit.append(y) return self def pop(self,z -1): if not lit: raise IndexError return lit.pop(z) def __str__(self): return str(lit) return Method() lst make_list([1,2,3,4,5,6,7,8,9]) print(lst) lst.add(5) print(lst) lst.pop(0) print(lst) make_list([1,2,3,4,5,6,7,8,9]) │ ▼ ┌─────────────────────────────┐ │ 栈帧make_list │ │ 局部变量 │ │ x [1,2,3,4,5,6,7,8,9] │ │ lit [1,2,3,4,5,6,7,8,9]│ ← 闭包捕获这个 │ │ │ class Method: │ │ 方法里访问 lit闭包 │ │ │ │ return Method() ──────────┼──► 返回实例 │ │ │ └─────────────────────────────┘ │ │ │ ▼ │ ┌─────────────┐ │ │ Method实例 │ │ │ (lst) │◄───────────┘ │ │ lit 被闭包引用 │ add(y) ─────┼──► lit.append(y) │ pop(z) ─────┼──► lit.pop(z) │ __str__() ──┼──► str(lit) └─────────────┘ │ ▼ 所有操作都修改同一个 lit 因为列表是可变对象闭包共享引用 法二使用字典或者条件判断语句来手动执行方法 # 法三返回函数对象动态加属性 def make_list(x): lit x def add(y): lit.append(y) def pop(z-1): lit.pop(z) # 创建一个函数对象当容器 def manager(): return lit.copy() manager.add add # 动态挂载方法 manager.pop pop return manager lst make_list([1, 2, 3]) lst.add(5) # ✅ 可以调用 print(lst()) # [1, 2, 3, 5] #法四from types import SimpleNamespace from types import SimpleNamespace def make_list(x): lit x def add(y): lit.append(y) def pop(z-1): lit.pop(z) return SimpleNamespace( addadd, poppop, getlambda: lit.copy() ) lst make_list([1, 2, 3]) lst.add(5) # ✅ 可以调用 print(lst.get()) # [1, 2, 3, 5] 3. 练习3若在函数内部直接给一个变量赋值但之前又在函数内部引用过该变量如 print(x); x5 会出现什么错误为什么如何修复 def demo(): print(x) # ← 先引用 x 5 # ← 后赋值 demo() # UnboundLocalError: local variable x referenced before assignment 出现在变量赋值前前被引用的错 global 、nonlocal、避免同名 4. 使用生成器表达式从 range(100) 中筛选出能被 3 和 5 整除的数并求出它们的和只使用生成器 表达式一次遍历。 sum 0 for i in range(100): if i %3 0 and i % 5 0: sum i print(sum) # a sum(x for x in range(100) if x % 3 0 and x % 5 0) # print(a) # print(list (x for x in range(100) if x % 3 0 and x % 5 0)) 5 实现一个生成器 cycle(iterable)无限循环遍历传入的可迭代对象。 例如 cycle(AB) 产生 A, B, A, B, …。 def cycle(iterable): it list(iterable) if not it: return while True: for x in it: yield x c cycle(AB) for i in range(8): print(next(c), end ) Day5 1. 练习题1计时装饰器 编写一个装饰器 timer打印函数的执行时间保留3位小数。 import time def timer(func): def wrapper(*args, **kwargs): start time.time() result func(*args, **kwargs) end time.time()-start print(f耗时{end:.3f}) return result return wrapper timer def result(): time.sleep(1) return result result() 2. 练习题2缓存装饰器 编写装饰器 cache对相同参数的计算结果进行缓存使用字典。 def cache(func): x {} #缓存字典 def wrapper(*args): if args not in x: result func(*args) x[args] result return result else: return x[args] return wrapper cache def expensive_function(n): print(f正在计算 {n}...) return n * n * n print(expensive_function(3)) # 正在计算 3... → 27 print(expensive_function(3)) # 直接返回缓存 → 27不打印正在计算 print(expensive_function(4)) # 正在计算 4... → 64 3. 限制参数类型 ⭐⭐ 编写装饰器 type_check强制检查函数参数的类型。 def type_check(*types): #str,int def gret(func):#greet def wrapper(*args, **kwargs):#内容 for x,y in zip(args,kwargs): if not isinstance(x,y): raise TypeError(f参数{x}必须是{y}类型但实际上是{type(x)}) return func(*args, **kwargs) return wrapper return gret type_check(str, int) #x,y # 要求第一个参数是str第二个是int def greet(name, times): return f{name} 说了 {times} 次你好 print(greet(Alice, 3)) # Alice 说了 3 次你好 print(greet(Bob, 2)) # TypeError: 参数 times 必须是 class int 类型