第二章练习答案
本页提供第二章所有练习的参考答案和详细解释。
00-function-basics
练习 1:温度转换
python
def celsius_to_fahrenheit(c):
return c * 9/5 + 32
def fahrenheit_to_celsius(f):
return (f - 32) * 5/9
print(celsius_to_fahrenheit(0)) # 32.0
print(celsius_to_fahrenheit(100)) # 212.0
print(fahrenheit_to_celsius(32)) # 0.0
print(fahrenheit_to_celsius(212)) # 100.0练习 2:默认参数
python
def power(base, exponent=2):
return base ** exponent
print(power(3)) # 9
print(power(2, 10)) # 1024练习 3:默认值陷阱
python
# 原代码问题
def append_to(element, target=[]):
target.append(element)
return target
list1 = append_to(1) # [1]
list2 = append_to(2) # [1, 2],不是 [2]!
# 解释:默认值 [] 在函数定义时创建一次,所有调用共享
# 修复
def append_to(element, target=None):
if target is None:
target = []
target.append(element)
return target
list1 = append_to(1) # [1]
list2 = append_to(2) # [2]练习 4:多返回值
python
def min_max(numbers):
return min(numbers), max(numbers)
minimum, maximum = min_max([3, 1, 4, 1, 5, 9, 2, 6])
print(f"Min: {minimum}, Max: {maximum}") # Min: 1, Max: 9练习 5:函数作为参数
python
def apply_operation(func, numbers):
return [func(n) for n in numbers]
def double(x):
return x * 2
print(apply_operation(double, [1, 2, 3, 4])) # [2, 4, 6, 8]01-scope-and-legb
练习 1:预测输出
python
x = 10
def func():
x = 20
print(f"Inside func: {x}")
func() # Inside func: 20
print(f"Outside func: {x}") # Outside func: 10解释:函数内的 x 是本地变量,不影响全局 x。
练习 2:全局计数器
python
counter = 0
def increment_global():
global counter
counter += 1
def reset_global():
global counter
counter = 0
increment_global()
increment_global()
print(counter) # 2
reset_global()
print(counter) # 0练习 3:nonlocal 实践
python
def make_counter():
count = 0
def increment():
nonlocal count # 关键修复
count = count + 1
return count
return increment
counter = make_counter()
print(counter()) # 1
print(counter()) # 2练习 4:LEGB 顺序
python
x = "global"
def outer():
x = "outer"
def middle():
x = "middle"
def inner():
print(x) # (1) "middle" - 找到 middle 的 x
inner()
print(x) # (2) "middle" - 本地 x
middle()
print(x) # (3) "outer" - 本地 x
outer()
print(x) # (4) "global" - 全局 x输出:
middle
middle
outer
global练习 5:避免内置名字
python
# 问题:list 和 sum 是内置名字
def calculate_length(list): # 覆盖了内置 list
sum = 0 # 覆盖了内置 sum
for item in list:
sum = sum + 1
return sum
# 修复:使用不同的变量名
def calculate_length(items):
total = 0
for item in items:
total = total + 1
return total
# 或直接使用内置 len
def calculate_length(items):
return len(items)02-closures-and-nonlocal
练习 1:温度转换器工厂
python
def make_converter(from_unit, to_unit):
if from_unit == 'C' and to_unit == 'F':
def convert(temp):
return temp * 9/5 + 32
elif from_unit == 'F' and to_unit == 'C':
def convert(temp):
return (temp - 32) * 5/9
else:
def convert(temp):
return temp
return convert
c_to_f = make_converter('C', 'F')
print(c_to_f(0)) # 32.0
print(c_to_f(100)) # 212.0练习 2:计数器三件套
python
def make_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
def decrement():
nonlocal count
count -= 1
return count
def value():
return count
return increment, decrement, value
inc, dec, val = make_counter()
inc()
inc()
dec()
print(val()) # 1练习 3:修复闭包陷阱
python
# 原代码问题
def make_multipliers():
return [lambda x: x * i for i in range(5)]
funcs = make_multipliers()
print([f(2) for f in funcs]) # [8, 8, 8, 8, 8],不是 [0, 2, 4, 6, 8]
# 解释:所有 lambda 捕获同一个变量 i,循环结束时 i=4
# 修复方法 1:默认参数
def make_multipliers():
return [lambda x, i=i: x * i for i in range(5)]
# 修复方法 2:额外闭包层
def make_multipliers():
def make_func(n):
return lambda x: x * n
return [make_func(i) for i in range(5)]
funcs = make_multipliers()
print([f(2) for f in funcs]) # [0, 2, 4, 6, 8]练习 4:累加器
python
def make_accumulator():
total = 0
def add(n):
nonlocal total
total += n
def get_total():
return total
return {'add': add, 'total': get_total}
acc = make_accumulator()
acc['add'](10)
acc['add'](20)
acc['add'](30)
print(acc['total']()) # 60练习 5:限流器(简化版)
python
import time
def make_rate_limiter(max_calls, period):
calls = []
def rate_limited(func):
def wrapper(*args, **kwargs):
nonlocal calls
now = time.time()
# 移除过期调用
calls = [t for t in calls if now - t < period]
if len(calls) >= max_calls:
print(f"Rate limit exceeded: {max_calls} calls per {period}s")
return None
calls.append(now)
return func(*args, **kwargs)
return wrapper
return rate_limited
@make_rate_limiter(3, 10)
def api_call():
print("API called")
return "Success"
# 测试
for i in range(5):
api_call()03-parameter-model
练习 1:可变参数求和
python
def multiply_all(*numbers):
if not numbers:
return 1
result = 1
for num in numbers:
result *= num
return result
print(multiply_all()) # 1
print(multiply_all(2, 3, 4)) # 24练习 2:字典合并
python
def merge(**dicts):
return dicts
d1 = merge(a=1, b=2)
d2 = merge(b=3, c=4)
print({**d1, **d2}) # {'a': 1, 'b': 3, 'c': 4}
# 或使用 *dicts
def merge(*dicts):
result = {}
for d in dicts:
result.update(d)
return result
print(merge({'a': 1}, {'b': 2}, {'c': 3})) # {'a': 1, 'b': 2, 'c': 3}练习 3:参数转发
python
def log_calls(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
print(f" args: {args}")
print(f" kwargs: {kwargs}")
return func(*args, **kwargs)
return wrapper
@log_calls
def add(a, b):
return a + b
print(add(3, 5))
# Calling add
# args: (3, 5)
# kwargs: {}
# 8练习 4:修复默认值陷阱
python
def create_student(name, courses=None):
if courses is None:
courses = []
courses.append("Math")
return {'name': name, 'courses': courses}
alice = create_student("Alice")
bob = create_student("Bob")
print(alice) # {'name': 'Alice', 'courses': ['Math']}
print(bob) # {'name': 'Bob', 'courses': ['Math']}练习 5:灵活的配置函数
python
def configure(required_param, /, optional_param=10, *, flag=False, **extra):
print(f"Required: {required_param}")
print(f"Optional: {optional_param}")
print(f"Flag: {flag}")
print(f"Extra: {extra}")
configure(1)
# Required: 1
# Optional: 10
# Flag: False
# Extra: {}
configure(2, 20, flag=True, x=100, y=200)
# Required: 2
# Optional: 20
# Flag: True
# Extra: {'x': 100, 'y': 200}
# configure(required_param=3) # TypeError: 仅限位置参数本章完成
完成这些练习后,你已经掌握了 Python 函数的核心机制:定义、作用域、闭包、参数模型。继续第三章学习对象、集合与文本数据。
回到第二章概览 · 返回Python 学习路线