0

I have already seen this post and even though the symptoms are similar, the way I am defining my class is different as I am using __init__:

>>> class foo(object):
...     def __init__(self,x):
...         self.x = x
... 
>>>

I next define an instance of this class:

>>> inst1 = foo(10)
>>> inst1.x
10

Now, I would like to copy the same instance into a new variable and then change the value of x:

>>> inst2 = inst1
>>> inst2.x = 20
>>> inst2.x
20

It seems, however, (like a class-level attribute) all data attributes are shared between inst1 and inst2 since changing the value of x for inst2 will also change that for inst1:

>>> inst1.x
20

I do know that an alternative method is to say:

>>>  inst2 = foo(20)

However, I don't like to do this because my actual class takes a lot of input arguments out of which I need to change only one or two specific data attribute(s) when creating different instances (i.e., the rest of input arguments remain the same for all instances. Any suggestions is greatly appreciated!

Community
  • 1
  • 1
user3076813
  • 499
  • 2
  • 6
  • 13

2 Answers2

2

You are not copying the class instance (the object). The following line

>>> inst2 = inst1

copies a reference of inst1. It does not copy the object.

Easy way to confirm this is to look at the result of the builtin id()-function, which results a unique memory address for each python object. The value for both inst2 and inst1 should be the same in this case.

And an easy way to solve it is to use Joran's answer.

msvalkon
  • 11,887
  • 2
  • 42
  • 38
2
class foo(object):
    def __init__(self,x):
         self.x = x
    def copy(self):
        return foo(self.x)

foo2 = foo1.copy()

is a pretty safe way to implement it

there is also the builtin copy method

from copy import deepcopy
foo2 = deepcopy(foo1)

if you define a __copy__ method, the copy.copy will use your own __copy__

class foo2:
     def __init__(self,val):
         self.state = 0
         self.val = val

     def __copy__(self):
         newfoo = foo2(self.val)
         newfoo.state = self.state
         print "Copied self:",self
         return newfoo

from copy import copy
f = foo2(5)
f2 = copy(f)  #will do copy we defined

this will make your code a somewhat more generic allowing you to just use the copy method on all objects without worrying about what the object is

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179