For a given object that may be an instance of a class, a built-in container or type, I would like to copy that object, but replace all instances of a given class with something else. I can do this with two calls to deepcopy
as shown below, but there may be a more straightforward approach.
Create some complex nested object:
class T(object):
pass
class A(object):
def __init__(self):
self.x = 10
self.t1 = T()
class B(object):
def __init__(self):
self.a = A()
self.y = 20
self.t2 = T()
b = B()
Get a mapping from ids to objects:
visited = {}
copy.deepcopy(b, visited)
Create a custom dict type to replace instances of T
with 100:
import collections
class Replacer(collections.MutableMapping):
def __init__(self, idmap):
self.store = dict()
self.idmap = idmap
def __getitem__(self, key):
if isinstance(self.idmap[key], T):
return 100
return self.store[key]
def __setitem__(self, key, value):
self.store[key] = value
def __delitem__(self, key):
del self.store[key]
def __iter__(self):
return iter(self.store)
def __len__(self):
return len(self.store)
Copy and replace all T
instances:
bb = copy.deepcopy(b, Replacer(visited))
In [121]: bb.t2
Out[121]: 100
In [122]: bb.a.t1
Out[122]: 100