Python实现B+树遇异常:新节点默认含值的原因排查
问题分析与解决
这绝对是Python可变默认参数的特性搞的鬼,哪怕你没主动操作val参数,背后的共享机制已经触发了问题。
问题根源
Python的函数默认参数是在函数定义阶段就创建实例,不是每次调用函数时重新生成。比如你大概率是这么定义的:
class BPlusNode: def __init__(self, isleaf=True, val=[], children=[]): self.isleaf = isleaf self.val = val self.children = children
这里的val=[]对应的列表对象,在__init__方法被定义时就已经存在了。所有调用BPlusNode()(不管传没传参数)的实例,都会共享同一个列表对象。
哪怕你没主动修改val,只要之前有任何一个BPlusNode实例在插入数据时往val里加过元素,后续新建的节点(比如你的new_root)的val就会带上之前的残留数据——因为它们用的是同一个列表。
解决方法
把可变默认参数换成None,在构造函数内部初始化新的可变对象:
class BPlusNode: def __init__(self, isleaf=True, val=None, children=None): self.isleaf = isleaf self.val = val if val is not None else [] self.children = children if children is not None else []
这样每次调用构造函数时,都会新建独立的空列表,每个节点的val和children都是专属的,不会再出现共享数据的问题。
为啥显式传val=[]就正常?
因为显式传入的[]是每次调用时全新创建的列表,不是那个被所有实例共享的默认对象,所以每个新节点的val都是独立的,自然不会有旧数据残留。
内容的提问来源于stack exchange,提问作者momo
相关产品推荐
相关产品推荐

