Python 函数与参数:编写不会共享默认列表的任务工具
把任务追加和平均值计算拆成函数,理解 return、关键字参数与可变默认参数,并为函数明确空输入和是否修改原数据的约定。
本节目标
把任务追加和平均值计算拆成函数,理解 return、关键字参数与可变默认参数,并为函数明确空输入和是否修改原数据的约定。
知识与使用场景
函数先要有清晰契约:接收什么、返回什么、是否改变调用方的数据。本节 add_task 接收标题和可选任务列表,返回一个追加后的新列表;average 接收非空数字列表,空列表时主动报告错误。
不要把 items=[] 当成“每次调用都创建空列表”。默认参数在函数定义执行时计算,如果在函数里修改它,后续调用就可能共享累积结果。使用 None 作为默认值,再在函数内部准备数据,能避免这个问题。
本节还有另一个设计选择:即使调用方传入列表,也使用 list 创建一份外层副本,让追加行为不改变原列表。当前元素是字符串,外层复制足够;若元素变成可变字典,内部对象的共享仍需要单独考虑。
完整示例
def add_task(title, items=None):
result = [] if items is None else list(items)
result.append(title)
return result
def average(values):
if not values:
raise ValueError("至少提供一条记录")
return sum(values) / len(values)
original = ["安装环境"]
print(add_task("练习函数", items=original))
print(original)
print(add_task("独立任务"))
print(f"平均值:{average([20, 30, 40]):.1f}")预期结果
['安装环境', '练习函数']
['安装环境']
['独立任务']
平均值:30.0运行与逐步理解
保存并运行后,第一行比原列表多一个任务,第二行仍只有安装环境,证明调用没有追加到原列表。第三次调用没有提供 items,也没有继承上一次结果。
items=original 是关键字传参,能让调用处直接表明参数含义。return 将结果交还给调用者;print 只把内容显示到终端,不能替代返回值。把这两个职责混在函数里,会让测试和复用变得困难。
average 在相除前拒绝空输入。本例约定 values 是数字列表,不接受任意生成器,也没有把字符串自动转换成数字。函数名简短不代表它应该处理所有可能对象,先写清边界,调用方才能正确使用。
常见问题与边界
if items is None与if not items含义不同,后者也会匹配空列表。- 只打印结果而没有 return,调用者拿到的是 None。
- 将函数内部 result 改成原列表引用,会改变这里“不修改输入”的约定。
- 类型注解可以帮助阅读和工具检查,但不会自动替你进行运行时输入校验。
动手练习
连续调用两次 add_task("复习"),检查两次是否各有一个元素;调用 average([]),使用 try/except 输出错误信息。
参考答案
两次独立调用都应返回 ["复习"]。空平均值应抛 ValueError,捕获后可显示“至少提供一条记录”。不要为了让空列表测试通过而返回一个没有业务含义的平均值。
文章回复
0 条公开回复