2 Generic (shallow and deep) copying operations
3 =============================================
9 x = copy.copy(y) # make a shallow copy of y
10 x = copy.deepcopy(y) # make a deep copy of y
12 For module specific errors, copy.error is raised.
14 The difference between shallow and deep copying is only relevant for
15 compound objects (objects that contain other objects, like lists or
18 - A shallow copy constructs a new compound object and then (to the
19 extent possible) inserts *the same objects* into in that the
22 - A deep copy constructs a new compound object and then, recursively,
23 inserts *copies* into it of the objects found in the original.
25 Two problems often exist with deep copy operations that don't exist
26 with shallow copy operations:
28 a) recursive objects (compound objects that, directly or indirectly,
29 contain a reference to themselves) may cause a recursive loop
31 b) because deep copy copies *everything* it may copy too much, e.g.
32 administrative data structures that should be shared even between
35 Python's deep copy operation avoids these problems by:
37 a) keeping a table of objects already copied during the current
40 b) letting user-defined classes override the copying operation or the
41 set of components copied
43 This version does not copy types like module, class, function, method,
44 nor stack trace, stack frame, nor file, socket, window, nor array, nor
47 Classes can use the same interfaces to control copying that they use
48 to control pickling: they can define methods called __getinitargs__(),
49 __getstate__() and __setstate__(). See the documentation for module
50 "pickle" for information on these methods.
53 # XXX need to support copy_reg here too...
58 Error
= error
# backward compatibility
61 """Shallow copy operation on arbitrary Python objects.
63 See the module's __doc__ string for more info.
67 copierfunction
= _copy_dispatch
[type(x
)]
71 except AttributeError:
73 "un(shallow)copyable object of type %s" % type(x
)
79 _copy_dispatch
= d
= {}
83 d
[types
.NoneType
] = _copy_atomic
84 d
[types
.IntType
] = _copy_atomic
85 d
[types
.LongType
] = _copy_atomic
86 d
[types
.FloatType
] = _copy_atomic
87 d
[types
.StringType
] = _copy_atomic
88 d
[types
.CodeType
] = _copy_atomic
89 d
[types
.TypeType
] = _copy_atomic
90 d
[types
.XRangeType
] = _copy_atomic
91 d
[types
.ClassType
] = _copy_atomic
95 d
[types
.ListType
] = _copy_list
99 d
[types
.TupleType
] = _copy_tuple
103 d
[types
.DictionaryType
] = _copy_dict
106 if hasattr(x
, '__copy__'):
108 if hasattr(x
, '__getinitargs__'):
109 args
= x
.__getinitargs
__()
110 y
= apply(x
.__class
__, args
)
113 y
.__class
__ = x
.__class
__
114 if hasattr(x
, '__getstate__'):
115 state
= x
.__getstate
__()
118 if hasattr(y
, '__setstate__'):
119 y
.__setstate
__(state
)
121 y
.__dict
__.update(state
)
123 d
[types
.InstanceType
] = _copy_inst
127 def deepcopy(x
, memo
= None):
128 """Deep copy operation on arbitrary Python objects.
130 See the module's __doc__ string for more info.
139 copierfunction
= _deepcopy_dispatch
[type(x
)]
142 copier
= x
.__deepcopy
__
143 except AttributeError:
145 "un-deep-copyable object of type %s" % type(x
)
148 y
= copierfunction(x
, memo
)
152 _deepcopy_dispatch
= d
= {}
154 def _deepcopy_atomic(x
, memo
):
156 d
[types
.NoneType
] = _deepcopy_atomic
157 d
[types
.IntType
] = _deepcopy_atomic
158 d
[types
.LongType
] = _deepcopy_atomic
159 d
[types
.FloatType
] = _deepcopy_atomic
160 d
[types
.StringType
] = _deepcopy_atomic
161 d
[types
.CodeType
] = _deepcopy_atomic
162 d
[types
.TypeType
] = _deepcopy_atomic
163 d
[types
.XRangeType
] = _deepcopy_atomic
165 def _deepcopy_list(x
, memo
):
169 y
.append(deepcopy(a
, memo
))
171 d
[types
.ListType
] = _deepcopy_list
173 def _deepcopy_tuple(x
, memo
):
176 y
.append(deepcopy(a
, memo
))
182 for i
in range(len(x
)):
190 d
[types
.TupleType
] = _deepcopy_tuple
192 def _deepcopy_dict(x
, memo
):
196 y
[deepcopy(key
, memo
)] = deepcopy(x
[key
], memo
)
198 d
[types
.DictionaryType
] = _deepcopy_dict
200 def _keep_alive(x
, memo
):
201 """Keeps a reference to the object x in the memo.
203 Because we remember objects by their id, we have
204 to assure that possibly temporary objects are kept
205 alive by referencing them.
206 We store a reference at the id of the memo, which should
207 normally not be used unless someone tries to deepcopy
211 memo
[id(memo
)].append(x
)
213 # aha, this is the first one :-)
216 def _deepcopy_inst(x
, memo
):
217 if hasattr(x
, '__deepcopy__'):
218 return x
.__deepcopy
__(memo
)
219 if hasattr(x
, '__getinitargs__'):
220 args
= x
.__getinitargs
__()
221 _keep_alive(args
, memo
)
222 args
= deepcopy(args
, memo
)
223 y
= apply(x
.__class
__, args
)
226 y
.__class
__ = x
.__class
__
228 if hasattr(x
, '__getstate__'):
229 state
= x
.__getstate
__()
230 _keep_alive(state
, memo
)
233 state
= deepcopy(state
, memo
)
234 if hasattr(y
, '__setstate__'):
235 y
.__setstate
__(state
)
237 y
.__dict
__.update(state
)
239 d
[types
.InstanceType
] = _deepcopy_inst
245 # Helper for instance creation without calling __init__
250 l
= [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
251 {'abc': 'ABC'}, (), [], {}]
259 def __init__(self
, arg
=None):
262 if __name__
== '__main__':
269 def __getstate__(self
):
270 return {'a': self
.a
, 'arg': self
.arg
}
271 def __setstate__(self
, state
):
272 for key
in state
.keys():
273 setattr(self
, key
, state
[key
])
274 def __deepcopy__(self
, memo
= None):
275 new
= self
.__class
__(deepcopy(self
.arg
, memo
))
278 c
= C('argument sketch')
288 l
.append({l
[1]: l
, 'xyz': l
[2]})
291 print map(repr.repr, l
)
292 print map(repr.repr, l1
)
293 print map(repr.repr, l2
)
294 print map(repr.repr, l3
)
297 print map(repr.repr, l
)
298 print map(repr.repr, l1
)
299 print map(repr.repr, l2
)
300 print map(repr.repr, l3
)
302 if __name__
== '__main__':