Из вашей проблемы неясно, почему вам нужно переопределить эти методы, поскольку вы не хотите вносить какие-либо изменения в методы копирования.
В любом случае, если вы хотите настроить глубокое копирование (например, путем совместного использования одних атрибутов и копирования других), вот решение:
from copy import deepcopy
def deepcopy_with_sharing(obj, shared_attribute_names, memo=None):
'''
Deepcopy an object, except for a given list of attributes, which should
be shared between the original object and its copy.
obj is some object
shared_attribute_names: A list of strings identifying the attributes that
should be shared between the original and its copy.
memo is the dictionary passed into __deepcopy__. Ignore this argument if
not calling from within __deepcopy__.
'''
assert isinstance(shared_attribute_names, (list, tuple))
shared_attributes = {k: getattr(obj, k) for k in shared_attribute_names}
if hasattr(obj, '__deepcopy__'):
# Do hack to prevent infinite recursion in call to deepcopy
deepcopy_method = obj.__deepcopy__
obj.__deepcopy__ = None
for attr in shared_attribute_names:
del obj.__dict__[attr]
clone = deepcopy(obj)
for attr, val in shared_attributes.iteritems():
setattr(obj, attr, val)
setattr(clone, attr, val)
if hasattr(obj, '__deepcopy__'):
# Undo hack
obj.__deepcopy__ = deepcopy_method
del clone.__deepcopy__
return clone
class A(object):
def __init__(self):
self.copy_me = []
self.share_me = []
def __deepcopy__(self, memo):
return deepcopy_with_sharing(self, shared_attribute_names = ['share_me'], memo=memo)
a = A()
b = deepcopy(a)
assert a.copy_me is not b.copy_me
assert a.share_me is b.share_me
c = deepcopy(b)
assert c.copy_me is not b.copy_me
assert c.share_me is b.share_me