刚发现一个若干月前写的日志草稿,那个“今天”都不知道是什么时候了……
这个bug挺搞笑的,而且可能也比较容易踩坑。而且ly平时效率超高,什么事都是一下子就做好了,而这个bug我和ly花半天时间debug才发现,发现后两人都哭笑不得,也让我印象深刻。
今天遇到一个很有趣的bug。
项目里用约4层嵌套的字典、列表等记录configuration,形如:
conf = {
'aa': {'a': 1, 'b': 2, 'c': [3, 4, 5]},
'bb': [1, 2, 3],
'cc': {
'aaa': [1, 2, 3],
'bbb': [
[9, 8, 7],
1,
]
}
}
然后用一个递归函数去读它:
def confValues(self, vals, conf=None):
if conf is None:
conf = self.conf
if isinstance(conf, collections.MutableMapping):
return {k: self.confValues(vals, conf=v) for k, v in conf.items()}
elif isinstance(conf, (list, tuple)):
return [self.confValues(vals, conf=v) for v in conf]
elif isinstance(conf, (str, unicode)) and conf.startswith("_"):
return self.varValue(conf, vals)
else:
return conf
稍微说一下,confValues这个函数内部实际上实现什么具体功能并不重要,只要知道关键的一点是它要把conf里的值作为参数conf递归下去就行了。
这套东西是同事写的,我用他的代码,改conf来适应我的需求。我的conf里的其中一个参数的值是None,于是程序一直出错,参数读不进去。我和同事debug了半天,终于发现原来玄机在confValues函数里conf变量初始化的设定中——递归函数用来标记初始化的无意义的None正好和conf里的有意义的值None冲突了。我把conf用来初始化的默认标记由None改成"initial_conf"(只要是不可能出现在conf里的值就行了),就没问题了。