1
#!/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

Hi, I don't understand the behavior of how the object is being built. Executing the code gives the following result :

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'}

But I was thinking it would give me (line 4 displays '1st' instead of '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'}

As you can see, if the value is passed by a variable, it's the variable content at the time of building the object that is taking into account. But with a dictionnary, it's the last value being affected and not the value affected when the objet is being built.

Can someone explain what is happening ?

1 Answers1

0

Basically you aren't creating a new dictionary object when you're overwriting the key 'secondEntry' the second time you set it in dict_value. What you're doing is instantiating an instance of ObjectFactory whose class attribute, self.valueA, has a pointer to that dictionary. Then when you update the value of the key 'secondEntry' in that dictionary the object that you instantiated which points to it will show an update as well because it is merely pointing to the dictionary rather than storing a "deep copy" of the state of that object at some point in time. That's why you're seeing the same value printed twice.

In programming there's this notion of shallow copies and deep copies. A Shallow Copy instantiates a new object that merely points to the old object. If the old object is updated the new object is effectively updated as well.

>>> #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}

A Deep Copy instantiates a new object with the state of the old object at the time of instantiation. In this case the underlying object was physically copied to the new address pointed to by the new object. If the old object changes the new object will see no change itself.

>>> #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}

Here's some valuable reading on shallow vs deep copy in python. Happy Coding!

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

zerocool
  • 308
  • 1
  • 10