先预测第二次调用
阅读函数def collect(x, bucket=[]): bucket.append(x); return bucket。第一次collect(3)得到[3];接着collect(8)得到[3,8],而不是[8]。这里默认参数对象在函数定义时求值,并被后续未传入该参数的调用复用。
不要用“Python随机缓存了结果”解释。把函数对象和它保存的默认列表画出来,记录每次append对同一个对象做了什么。
用None表达未提供参数
常见改法是def collect(x, bucket=None),函数内先判断if bucket is None: bucket=[],然后追加并返回。这样每次未提供bucket时会创建新的列表。
不宜写if not bucket作为替代,因为用户显式传入空列表时,空列表也为假值,会被换成另一个列表,破坏“修改传入对象”的原本语义。
测试应同时覆盖两种使用方式
设计三个检查:不传列表连续调用,两次结果应独立;传入已有列表,应按约定原地更新;传入空列表,也应保留它的身份。先决定函数是否允许副作用,再选测试预期。
默认参数是不可变值时并不产生同一种可变状态问题。但函数返回值若包含可变对象,仍要检查调用者是否共享引用。将最小复现代码和预期输出带到编程课程辅导,通常比整份作业更利于讨论。
参考资料
下一步
如需大学专业课程或 Tutorial 学习支持,请在咨询中填写模块名称、学习目标和已尝试的步骤。具体教学安排须确认,计分作业由学生独立完成。
