1

I create an instance of class A, objA1 whose objA1.data stored something to be processed later. Then I create an instance of class B, objB1, by passing objA1 into the instance constructor:

objB1 = B(objA1...)

objA1 is assigned to an attribute of objB1:

objB1.obj = objA1

Afterwards, a method of objB1 is called to process objB1.obj.data. objB1.obj.data is modified by the method doubtlessly. But is objA1.data modified at the same time?

enrico.bacis
  • 30,497
  • 10
  • 86
  • 115
  • possible duplicate of [Trouble understanding passing values and references in Python](http://stackoverflow.com/questions/7838005/trouble-understanding-passing-values-and-references-in-python) – metatoaster Aug 13 '14 at 23:03

1 Answers1

0

If the data is immutable (like a string, tuple) you are safe, but if, for example is mutable (like a list, dict), yes the data passed by reference may be modified. Let's make an example:

class A:
    def __init__(self):
        self.data = ['important']

class B:
    def __init__(self, obj):
        self.obj = obj

    def unsafe(self):
        data = self.obj.data
        # process data
        data[0] = 'nothing here'

objA1 = A()
print objA1.data    # ['important']

objB1 = B(objA1)
objB1.unsafe()
print objA1.data    # ['nothing here']

Back to Safety

You could just make a copy before processing. You need to import copy:

import copy

Now you can use copy.deepcopy in the method __init__ of class B like this:

class B:
    def __init__(self, obj):
        self.obj = copy.deepcopy(obj)

Let's try again:

objA1 = A()
print objA1.data    # ['important']

objB1 = B(objA1)
objB1.unsafe()
print objA1.data    # ['important']

The important data is safe!

You can also create a safe method in B and copy only data. Here a shallow copy may suffice:

class B:
    # ...
    def safe(self):
        data = copy.copy(self.obj.data)
        # process data
        data[0] = 'nothing here'
Community
  • 1
  • 1
enrico.bacis
  • 30,497
  • 10
  • 86
  • 115