可变默认参数-(为什么)我的代码是危险的



我的代码在pylint:中触发警告

def getInsertDefault(collection=['key', 'value'], usefile='defaultMode.xml'):
return doInsert(collection,usefile,True)

警告非常清楚,它是可变默认参数,我明白在一些情况下,它可能会给人一种错误的印象。SA上已经有几个帖子了,但感觉这里没有涵盖这一个。大多数问题和示例都涉及空列表,这些列表引用不足,可能会导致错误。

我也知道将代码更改为getInsertDefault(collection=None ...)是更好的做法,但在这种默认初始化方法中,我不打算对列表做任何事情,除了阅读,(为什么(我的代码有危险或可能导致陷阱?

--编辑--

切中要害:为什么空字典在Python中是一个危险的默认值?会回答这个问题。有点:我知道我的代码违反了惯例,可能会导致陷阱——但在这种非常具体的情况下:我安全吗?

我发现评论中的建议很有用,可以使用collection=('key', 'value'),因为它是传统的且安全的。不过,出于纯粹的兴趣:我之前的尝试是否会造成某种重大问题?

假设doInsert()(以及doInsert正在调用的任何代码(只读取collection,则实际上不存在即时问题,只是一颗定时炸弹。

一旦看到此列表的代码的任何部分开始对其进行更改,您的代码就会以最意想不到的方式中断,你可能很难调试这个问题(想象一下,如果更改的是几十个堆栈帧之外的第三部分库函数……在最好的情况下,问题及其根本原因仍然在调用堆栈的同一个直接分支中——它可能存储为某个实例属性,并被一些不相关的调用突变,然后你就可以获得一些乐趣了(。

现在,这种情况发生的几率很低,但考虑到潜在的子问题(这可能只是偶尔导致错误的结果,而不一定会导致程序崩溃(和难以跟踪的错误,你应该三思而后行,然后再假设这真的是"安全的"。

最新更新