提问人:Marcus Whybrow 提问时间:3/13/2010 最后编辑:Karl KnechtelMarcus Whybrow 更新时间:9/3/2022 访问量:64685
Python 是否会在赋值时复制对象?
Does Python make a copy of objects on assignment?
问:
当我尝试此代码时:
dict_a = dict_b = dict_c = {}
dict_c['hello'] = 'goodbye'
print(dict_a)
print(dict_b)
print(dict_c)
我预计它只会初始化 和 字典,然后在 中分配一个键,从而导致dict_a
dict_b
dict_c
dict_c
{}
{}
{'hello': 'goodbye'}
但它似乎反而具有复制效果:
{'hello': 'goodbye'}
{'hello': 'goodbye'}
{'hello': 'goodbye'}
为什么?
答:
这是因为在 Python 中,变量(名称)只是对单个对象的引用。当您分配 时,您实际上是在将内存地址(或指针,如果您愿意的话)从 复制到 。该字典仍然有一个实例。dict_a = dict_b
dict_b
dict_a
若要获得所需的行为,请使用该方法,或者使用 if 您的字典可能具有嵌套的字典或其他嵌套对象。dict.copy
copy.deepcopy
>>> a = {1:2}
>>> b = a.copy()
>>> b
{1: 2}
>>> b[3] = 4
>>> a
{1: 2}
>>> b
{1: 2, 3: 4}
>>>
评论
id()
dir(1)
a = b = c = 1; a +=1
1
a
2
您的第一个赋值将相同的字典对象分配给变量 dict_a、dict_b 和 dict_c。它等价于 dict_c = {};dict_b = dict_c;dict_a = dict_c。
正如 danben 之前所说,你只是将相同的字典复制到 3 个变量中,以便每个变量都引用同一个对象。
为了获得你想要的行为,你应该在每个变量中实例化一个不同的字典:
>>> dict_a, dict_b, dict_c = {}, {}, {}
>>> dict_c['hello'] = 'goodbye'
>>> print dict_a
{}
>>> print dict_b
{}
>>> print dict_c
{'hello': 'goodbye'}
>>>
评论
即使
>>> dict_a, dict_b, dict_c = {}, {}, {}
在大多数情况下是正确的方法,当它超过 3 时,它看起来很奇怪
想象
>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
如果我想初始化 3 个以上的东西,我使用
>>> a, b, c, d, e, f, = [dict() for x in range(6)]
评论
{}
dict()
{}
{}
dict()
import dis; print dis.dis(lambda: dict()); print dis.dis(lambda:{})
dis
dicts = {x: {} for x in ["a", "b", "c"]}
我同意上面所说的。这里的关键是,在 Python 中,赋值表示对对象的引用。 我试图自己掌握这个概念,我认为了解在哪种情况下创建新对象以及何时更改现有对象是否重要。
在上面的示例中,行:
dict_c['hello'] = 'goodbye'
不会创建新对象。它仅更改 dict_a、dict_b 和 dict_c 引用的对象。
相反,如果你写了:
dict_c = {'hello': 'goodbye'}
它将创建一个新对象,该对象将由dict_c引用。Dict_a 和 dict_b 仍然指向空对象。
在这种情况下,如果运行:
print dict_a
print dict_b
print dict_c
你会得到:
{}
{}
{'hello': 'goodbye'}
评论
{}