我有以下代码:
def modify_dict(my_dict):
my_dict = {'b': 2}
print(my_dict)
def main():
my_dict = {'a': 1}
modify_dict(my_dict)
print(my_dict)
if __name__ == '__main__':
main()
它的输出是:
{'b': 2}
{'a': 1}
我的问题是为什么对函数内的字典所做的更改没有反映在main()
函数中?
另外,如何更新函数内的字典,以便更改反映在函数外部?
答案 0 :(得分:1)
my_dict
的{{1}}参数是函数的局部变量。它包含对您的字典的引用,但它本身只是一个局部变量。如果你进入并修改它指向的字典,那就行了。例如:
modify_dict
将添加到您的字典中。实际上,您只需将新字典分配给函数中名为my_dict的局部变量。
作为@vmonteco suggests,实现此目的的最佳方法是从函数中返回新字典并分配返回值。
答案 1 :(得分:1)
只需返回新的字典,并将此返回值分配给my_dict
函数中的main()
。
def modify_dict():
my_dict = {'b': 2}
print(my_dict)
return my_dict
def main():
my_dict = {'a': 1}
my_dict = modify_dict()
print(my_dict)
if __name__ == '__main__':
main()
输出应为:
{'b': 2}
{'b': 2}
更简单的方法是直接返回{'b' : 2}
,甚至不用制作本地my_dict
变量,如下所示:
def modify_dict():
return {'b' : 2}
这与将新值{'b' : 2}
直接分配给变量(my_dict = {'b' : 2}
)基本相同,你甚至不需要一个函数,除非新的值为你的词典取决于它之前的价值。
my_dict
函数中的main()
变量?将变量传递给函数时,函数不会直接使用它。 它只使用此变量的副本,这是一个仅存在于函数中的新变量。
因此,在某种程度上,您的案例中有两个my_dict
个变量:
- modify_dict()
功能中的一个。
- 还有main()
函数中的那个。
在my_dict
功能中修改modify_dict()
时,您不需要编辑main()
功能中的一个,只需复制一份。
答案 2 :(得分:1)
这是一个有趣的问题,我会试着尝试一下。我的主要编程语言是Java,但我认为CPython和JVM在这种情况下是相同的。
在程序运行时,它有堆栈和堆,堆栈用于方法调用上下文存储,堆用于全局对象存储。
好的,然后,使用代码作为示例
第1步。
my_dict = {'a': 1}
它会在堆中创建一个dict(1) {' a':1} ,然后my_dict为引用到dict(1)的内存地址,这意味着my_dict现在指向内存地址,但不是{' a':1}本身。
第2步。
my_dict = modify_dict()
好的,然后我们在main函数中调用modify_dict函数,程序将主函数的上下文放入堆栈(stack1),并使用 my_dict modify_dict >作为参数,现在,程序将为函数modify_dict创建一个新堆栈,并且创建参数的副本,这意味着my_dict参数现在是引用副本(指向堆中的dict(1)与main中的my_dict变量具有相同的值,但是它是副本)。 (事实上,这个问题已在这里回答)
第3步:
my_dict = {'b': 2}
my_dict (堆中 dict(1)的参考点)现在分配给堆中的新dict(2),现在记住 my_dict与main 中的my_dict不同,它们指向堆中的两个不同的dict 。
第4步:
程序返回main函数,程序将从堆栈中取出东西, my_dict现在指向dict(1),而dict(1)不在函数modify_dict中修改
抱歉我的英语不好:)