为何全局字典变量inside_dictionary的值会意外改变?
问题解析:Python字典引用导致的意外行为
需求与预期结果
我们需要构建一个存储父子关系的字典,预期输出为:
{'Ben': {'child': 'John'}, 'jonathan': {'child': 'benjamin'}}
编写的代码
main_dictionary = {} inside_dictionary = {} parent_key = 'Ben' child_key = 'child' def addtoDictionary(): parent_key = 'jonathan' child_name = 'benjamin' main_dictionary[parent_key] = inside_dictionary # 预期这里是空字典{} print("inside fcn: ",main_dictionary) main_dictionary[parent_key][child_key] = child_name # 预期child值为"benjamin" print("inside fcn: ",main_dictionary) return() main_dictionary[parent_key] = inside_dictionary child_name = 'John' main_dictionary[parent_key][child_key] = child_name # 注释中笔误,实际应为"John" print(main_dictionary) addtoDictionary()
实际运行结果
{'Ben': {'child': 'John'}} inside fcn: {'Ben': {'child': 'John'}, 'jonathan': {'child': 'John'}} inside fcn: {'Ben': {'child': 'benjamin'}, 'jonathan': {'child': 'benjamin'}}
疑问解答
为什么函数内的inside_dictionary不是空字典?
核心原因是Python中字典是可变对象,赋值操作传递的是对象的引用,而不是创建新的副本。
你定义的inside_dictionary是一个全局的空字典,主代码中第一次执行main_dictionary[parent_key] = inside_dictionary时,是把这个空字典的引用绑定到了main_dictionary['Ben']上。之后你给main_dictionary['Ben']['child']赋值为'John',本质是直接修改了inside_dictionary这个字典本身——因为两者指向内存中同一个对象。
当你在函数里执行main_dictionary[parent_key] = inside_dictionary时,你并没有拿到一个新的空字典,而是把已经被修改过的inside_dictionary的引用又绑定到了main_dictionary['jonathan']上。此时main_dictionary['Ben']和main_dictionary['jonathan']指向同一个字典对象,所以修改任意一个的child值,另一个都会同步变化。
为什么改成main_dictionary[parent_key] = {}就正常?
因为{}每次都会创建一个全新的空字典对象,每个父键对应的都是独立的字典实例,互相之间没有引用关联,修改其中一个不会影响其他的。
如何复用类似inside_dictionary的变量?
不能直接复用同一个全局字典对象,而是每次需要的时候生成新的空字典实例:
- 可以直接在赋值时用
{}创建新字典,就像你测试的正确写法那样。 - 如果需要复用一个"模板"(比如后续字典需要固定键结构),可以定义一个生成字典的函数,比如:
之后在需要的地方调用这个函数获取新字典:def create_child_dict(): return {} # 或者返回带初始结构的字典,比如{'child': None}main_dictionary[parent_key] = create_child_dict()
内容的提问来源于stack exchange,提问作者Roberto
相关产品推荐
相关产品推荐

