Python: deepcopy does not work on user-defined classes?
Asked Answered
W

2

13

In the following example I would expect deepcopy to create a copy of field and not just copy the reference. What happens here and is there an easy way around it?

from copy import deepcopy

class Test:
    field = [(1,2)]

t1 = Test()
t2 = deepcopy(t1)

t2.field[0]=(5,10)

print t1.field # [(1,2)] expected but [(5,10)] obtained
print t2.field # [(5,10)] expected

Output:

[(5, 10)]
[(5, 10)]
Williams answered 21/8, 2013 at 17:46 Comment(1)
possible duplicate of How to copy a python class?Norvin
P
16

Deep copying (by default) only applies to instance level attributes - not class level - It doesn't make much sense that there's more than one unique class.attribute...

Change your code to:

class Test:
    def __init__(self):
        self.field = [(1,2)]
Pyrogen answered 21/8, 2013 at 17:48 Comment(2)
Unless he overrides __copy__/__deepcopy__. Still though, that would be pretty odd.Takara
This is actually not an answer to the question, but a workaround to the problem. If you dont want to/cant instantiate the class in every case, e.g.: you have a @classmethod, you cannot apply this workaround...Norvin
L
0

Another approach with python 3.8 (I am not sure about previous versions) could be creating a __init__ method that deep-copies every class level attribute, like:

from copy import deepcopy

class Test:
    field = [(1,2)]
    def __init__(self):
        for attr in dir(self):
            if not attr.startswith('_'):
                setattr(self, attr, deepcopy(getattr(self, attr)))

t1 = Test()
t2 = deepcopy(t1)

t2.field[0]=(5,10)

print(t1.field) # [(1,2)]
print(t2.field) # [(5,10)]

of course you can also replace the dir with inspect.getmembers.

Lorrettalorri answered 15/2, 2023 at 23:41 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Girasol

© 2022 - 2024 — McMap. All rights reserved.