from copy import deepcopy from pickle import dumps, loads from datetime import datetime def state_setter(obj, state): print(f"setting state with: {state}") obj._state = state["_state"] class Pickleable: def __init__(self): self._state = datetime.now() def __str__(self): return str(self._state) def __reduce__(self): return ( object.__new__, (type(self),), {"_state": self._state}, None, None, state_setter, ) def deep_copier(arg, memo=None): print(f"deepcopying with: arg={arg}, memo={memo}") return deepcopy(arg, memo) class Copyable: def __init__(self): self._state = datetime.now() def __str__(self): return str(self._state) def __reduce__(self): return ( object.__new__, (type(self),), {"_state": self._state}, None, None, deep_copier, ) p1 = Pickleable() c1 = Copyable() # these work: p1_p = loads(dumps(p1)) c1_c = deepcopy(c1) # these fail: p1_c = deepcopy(p1) c1_p = loads(dumps(c1))