DevCN
菜单
全部文章快讯开发深度热点

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 Noneif not items 含义不同,后者也会匹配空列表。
  • 只打印结果而没有 return,调用者拿到的是 None。
  • 将函数内部 result 改成原列表引用,会改变这里“不修改输入”的约定。
  • 类型注解可以帮助阅读和工具检查,但不会自动替你进行运行时输入校验。

动手练习

连续调用两次 add_task("复习"),检查两次是否各有一个元素;调用 average([]),使用 try/except 输出错误信息。

参考答案

两次独立调用都应返回 ["复习"]。空平均值应抛 ValueError,捕获后可显示“至少提供一条记录”。不要为了让空列表测试通过而返回一个没有业务含义的平均值。

DISCUSSION

文章回复

0 条公开回复
未登录回复需要审核后公开
还没有回复,欢迎参与讨论。