3

I'm trying to create a simple deepcopy function that simply skipps some object attributes, but my prototype implementation below goes into infinite recursion. Is this the right way to proceed?

from copy import deepcopy class Foo(): def __init__(self): self.copied = 1 self.skipped = 2 def __deepcopy__(self, memo): obj = type(self)() for attr in dir(self): if attr in ['skipped']: continue attr_copy = deepcopy(getattr(self, attr), memo) setattr(obj, attr, attr_copy) pass return obj o1 = Foo() o2 = deepcopy(o1) 

(I'm aware in this simple case I can just use delattr on a new instance, but for more complex cases I would like to use the deepcopy functionality.)

1
  • I think the problem is that what you want isn't actually simple. E.g. because you use obj = type(self)() your code won't work if Foo needs some parameter for __init__() other than self. You should examine the (python) source code of the copy module; it's in your python installation Lib folder. Commented Jun 21, 2021 at 22:32

2 Answers 2

0

Not sure if it is the best or proper approach, but I finally came up with the following:

def __deepcopy__(self, memo): cls = self.__class__ obj = cls.__new__(cls) memo[id(self)] = obj for k, v in self.__dict__.items(): if k == ['skipped']: v = dict() setattr(obj, k, deepcopy(v, memo)) pass return obj 
Sign up to request clarification or add additional context in comments.

Comments

-1

I came accross this looking for a way to skip a non picklable attribute and based on JacobP's answer I'm using the below. It uses the same reference to skipped as the original instance.

def __deepcopy__(self, memo): cls = self.__class__ obj = cls.__new__(cls) memo[id(self)] = obj for k, v in self.__dict__.items(): if k not in ['skipped']: v = copy.deepcopy(v, memo) setattr(obj, k, v) return obj 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.