import copy class CopyTestClass(object): def __init__(self, q, w): self._a = q self._b = w self._cache = {} def __copy__(self): # Create a new instance cls = self.__class__ result = cls.__new__(cls) # Copy all attributes result.__dict__.update(self.__dict__) # Return updated instance return result def __deepcopy__(self, memo): # Create a new instance cls = self.__class__ result = cls.__new__(cls) # Don't copy self reference memo[id(self)] = result # Don't copy the cache memo[id(self._cache)] = self._cache.__new__(dict) # Deep copy all other attributes for k, v in self.__dict__.items(): setattr(result, k, copy.deepcopy(v, memo)) # Return updated instance return result class CopyTestClassWithSlots(object): __slots__ = ('_a', '_b', '_cache') def __init__(self, q, w): self._a = q self._b = w self._cache = {} def __copy__(self): # Create a new instance cls = self.__class__ result = cls.__new__(cls) # Copy all attributes for var in self.__slots__: setattr(result, var, copy.copy(getattr(self, var))) # Return updated instance return result def __deepcopy__(self, memo): # Create a new instance cls = self.__class__ result = cls.__new__(cls) # Don't copy self reference memo[id(self)] = result # Don't copy the cache memo[id(self._cache)] = self._cache.__new__(dict) # Deep copy all other attributes for var in self.__slots__: setattr(result, var, copy.deepcopy(getattr(self, var), memo)) # Return updated instance return result # Testing deep copy with __dict__ test1 = CopyTestClass(q=10, w=[1.0 for _ in range(10)]) test1._cache["coins"] = 120 test1c = copy.deepcopy(test1) # Testing copy with __slots__ test2 = CopyTestClass(q=25, w=None) test2c = copy.copy(test2) # Testing deep copy with __slots__ test3 = CopyTestClass(q=[1.0 for _ in range(4)], w=None) test3._b = "a string" test3._cache['test_me'] = 1020 test3c = copy.deepcopy(test3)