Python函数默认字典参数仅首次初始化的技术问询
Python可变默认参数的陷阱:为什么你的字典会保留之前的内容?
问题原理
Python的函数默认参数不是在每次调用函数时初始化的,而是在函数被定义的那一刻就完成了初始化。对于像字典、列表这类可变对象,这个初始化后的对象会被该函数的所有调用共享。
回到你的代码:
def walkDirectory(path, fileDataBySize=dict(), ...):
当Python解释器执行到这个函数定义时,就会创建一个空字典作为fileDataBySize的默认值。第一次顶层调用walkDirectory时,你没传这个参数,用的就是这个默认字典,递归过程中它被不断填充数据。而后续的顶层调用,如果你仍然不传fileDataBySize,Python会直接复用之前已经被修改过的那个默认字典,导致之前的数据残留。
你的理解疏漏
你误以为默认参数会在每次函数调用时重新创建,但实际上这个规则只适用于不可变对象(比如整数、字符串、元组)——因为它们无法被修改,每次调用用同一个值不会有问题。但可变对象(字典、列表)可以被修改,共享同一个实例就会导致数据被累积。
修正方案
方案1:用None作为默认值,在函数内部初始化字典
这是Python社区处理这类问题的标准做法:
def walkDirectory(path, fileDataBySize=None, ...): # 顶层调用时如果没传参数,创建新字典 if fileDataBySize is None: fileDataBySize = dict() ... if ...: # 递归调用时传入已有的字典,保证数据共享 walkDirectory(subpath, fileDataBySize, ...) ... return fileDataBySize
这样每次顶层调用如果不传fileDataBySize,都会在函数内部生成一个新的空字典;递归调用时则传入已有的字典,确保递归过程中能正常收集所有文件数据。
方案2:顶层调用时显式传入空字典
每次调用时手动传一个新的空字典:
fileDataBySize = walkDirectory(directoryToProcess, dict(), ...)
但这种方式依赖调用者记得传参,不如方案1可靠,不推荐作为长期解决方案。
内容的提问来源于stack exchange,提问作者Ian
相关产品推荐
相关产品推荐

