通过引用类的字典属性了解副本

时间:2019-07-18 13:06:02

标签: python dictionary reference copy

为什么在以下MWE的行new.dic2['a'] = i处有引用副本,而在new.dic1 = {'a':i}上却没有?


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

class a():
    dic1 = {'a':None}
    dic2 = {'a':None}

lst = []

print('creating list')
for i in range(2):
    new = a()
    new.dic1 = {'a':i}
    new.dic2['a'] = i

    print("lst[%d].dic1['a'] = %d" % (i,new.dic1['a']))
    print("lst[%d].dic2['a'] = %d" % (i,new.dic2['a']))
    lst.append(new)

print('showing list')
for i in range(len(lst)):
    print("lst[%d].dic1['a'] = %d" % (i,lst[i].dic1['a']))
    print("lst[%d].dic2['a'] = %d" % (i,lst[i].dic2['a']))

此打印

创建列表:

lst[0].dic1['a'] = 0
lst[0].dic2['a'] = 0
lst[1].dic1['a'] = 1
lst[1].dic2['a'] = 1

显示列表:

lst[0].dic1['a'] = 0
lst[0].dic2['a'] = 1
lst[1].dic1['a'] = 1
lst[1].dic2['a'] = 1

1 个答案:

答案 0 :(得分:2)

使用new = a()创建新实例时,最初的new实例既不包含dic1也不包含dic2,但通过类继承它们。但是当您进行以下分配时:

new.dic1 = {'a':i}

这将在实例dic1中为new创建一个实例变量。因此,此时new包含一个实例变量dic1,但仍从类中选取dic2

如果您随后对new.dic1进行更改,则它们对new是本地的,因为它具有自己的dic1副本。但是,如果您对new.dic2进行了更改,它将更改类变量a.dic2

第二次遍历循环,创建了一个新的类实例,在将其分配给new.dic1之后,它也有自己的实例new.dic1,但是两个实例中的new.dic2实例在访问时会引用回a.dic2。因此,dic2的更改会同时反映在两个实例和类本身中,而dic1的更改对于每个实例都是本地的。