永远不要使用 Python 的可变值作为默认值

发布于 2025-07-05 05:32:07 字数 1185 浏览 1 评论 0

丹尼尔·陶西斯在 Unsplash 上的照片

会发生什么,为什么会发生,怎么做才能避免。

可变违约的后果

我们编写了一个函数,它将学生的姓名和分数作为参数,并根据提供的分数将“通过”或“未通过”添加到字典中。为了方便起见,由用户决定她是否要提供字典。如果她不做,我们想重新开始。我们的第一次尝试是这样的:

这看起来不错,但是让我们在不提供字典的情况下连续使用这个函数两次,看看会发生什么:

从输出中可以看到,每个函数调用都将 指向同一个对象 。这不是我们想要发生的!

重复使用对象的原因

让我们来搞清楚这种行为。如果我们试图访问函数外部的变量,Python 会返回一个 NameError 。这表明变量作用域按预期工作。然而,该值必须在某处可用;否则,Python 无法在第二次函数调用期间添加键。

让我们再深入一层。下面是同一函数的调整版本,它也返回字典的 内存地址

如果我们查看结果,我们可以看到两个调用都引用了内存中的同一个对象。我们也能够直接从内存中提取值。总之,我们不能通过变量访问这个值,但是它在内存中是安全可靠的。那么, 让它活下去的隐藏引用 在哪里呢?

答案在于 Python 加载函数的方式。也就是说,每当 Python 第一次加载一个函数时,它也会创建对其默认值的 引用。也就是说,对函数的引用隐藏了对字典的引用。

如何防止这种行为

为了防止这种不必要的行为,我们需要将引用的创建转移到函数本身中。这确保了每个函数调用都使用新的引用而不是旧的引用。修改后的函数如下所示:

如您所见,现在每个函数调用都指向另一个内存地址。这些对象不再相互干扰。这是一个针对较小主题的新“快速修复”格式的实验。让我知道你对它的看法,在评论中或者在推特上。我也很乐意在 LinkedIn 上联系。感谢您的阅读!

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。