Python - 传递dictionnary以构建对象时的行为

时间:2018-03-22 16:07:55

标签: python

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

#from fonctions import ObjectFactory

class ObjectFactory():
    def __init__(self, valueA) :
        self.valueA = valueA

list_objects = []

list_objects.append(ObjectFactory( 'Without variable'))

valueA = '1st value via variable'
list_objects.append(ObjectFactory( valueA))
valueA = '2nd value via variable'
list_objects.append(ObjectFactory( valueA))

dict_value = {}
dict_value['firstEntry'] = 'value unchanged'
dict_value['secondEntry'] = '1st value via dict'
list_objects.append(ObjectFactory( dict_value))
dict_value['secondEntry'] = '2nd value via dict'
list_objects.append(ObjectFactory( dict_value))


for my_object in list_objects :
    #print my_object
    print my_object.valueA

您好, 我不了解对象的构建方式。 执行代码会得到以下结果:

Without variable
1st value via variable
2nd value via variable
{'firstEntry': 'value unchanged', 'secondEntry': '2nd value via dict'}
{'firstEntry': 'value unchanged', 'secondEntry': '2nd value via dict'}

但我认为它会给我(第4行显示' 1st'而不是' 2nd')

Without variable
1st value via variable
2nd value via variable
{'firstEntry': 'value unchanged', 'secondEntry': '1st value via dict'}
{'firstEntry': 'value unchanged', 'secondEntry': '2nd value via dict'}

如您所见,如果值由变量传递,则它是构建考虑对象时的变量内容。 但是对于一个词典,它是受影响的最后一个值,而不是在构建对象时受影响的值。

有人可以解释发生了什么吗?

1 个答案:

答案 0 :(得分:0)

基本上,当你第二次在dict_value中设置键'secondEntry'时,你不会创建一个新的字典对象。你正在做的是实例化ObjectFactory的一个实例,它的类属性self.valueA有一个指向该字典的指针。然后,当您更新该字典中的键'secondEntry'的值时,您实例化的指向它的对象也将显示更新,因为它只是指向字典而不是存储“深层副本“某个时刻该物体的状态。这就是为什么你看到打印两次的相同值。

在编程中,存在浅拷贝和深拷贝的概念。 浅复制实例化一个仅指向旧对象的新对象。如果更新旧对象,则还有效地更新新对象。

>>> #SHALLOW COPY
>>> d = {}
>>> d['first'] = 1
>>> d['second'] = 2
>>> c = d
>>> print c
{'second': 2, 'first': 1}
>>> d['first'] = 42
>>> print c
{'second': 2, 'first': 42}

Deep Copy 在实例化时使用旧对象的状态实例化一个新对象。在这种情况下,底层对象被物理复制到新对象指向的新地址。如果旧对象发生更改,则新对象将看不到任何更改。

>>> #DEEP COPY
>>> print d
{'second': 2, 'first': 42}
>>> import copy
>>> c = copy.deepcopy(d)
>>> d['first'] = -7
>>> print d
{'second': 2, 'first': -7}
>>> print c
{'second': 2, 'first': 42}

这里有一些关于python中浅层和深层副本的有价值的阅读。快乐的编码!

https://www.geeksforgeeks.org/copy-python-deep-copy-shallow-copy/