Back to index

python3.2  3.2.2
Classes | Functions | Variables
copy Namespace Reference

Classes

class  Error
class  _EmptyClass

Functions

def copy
def _copy_immutable
def _copy_with_constructor
def _copy_with_copy_method
def deepcopy
def _deepcopy_atomic
def _deepcopy_list
def _deepcopy_tuple
def _deepcopy_dict
def _deepcopy_method
def _keep_alive
def _reconstruct
def _test

Variables

 error = Error
 PyStringMap = None
list __all__ = ["Error", "copy", "deepcopy"]
dictionary _copy_dispatch = d{}
tuple t = getattr(types, "CodeType", None)
dictionary _deepcopy_dispatch = d{}
 a
 arg
 fp

Detailed Description

Generic (shallow and deep) copying operations.

Interface summary:

import copy

x = copy.copy(y)        # make a shallow copy of y
x = copy.deepcopy(y)    # make a deep copy of y

For module specific errors, copy.Error is raised.

The difference between shallow and deep copying is only relevant for
compound objects (objects that contain other objects, like lists or
class instances).

- A shallow copy constructs a new compound object and then (to the
  extent possible) inserts *the same objects* into it that the
  original contains.

- A deep copy constructs a new compound object and then, recursively,
  inserts *copies* into it of the objects found in the original.

Two problems often exist with deep copy operations that don't exist
with shallow copy operations:

 a) recursive objects (compound objects that, directly or indirectly,
    contain a reference to themselves) may cause a recursive loop

 b) because deep copy copies *everything* it may copy too much, e.g.
    administrative data structures that should be shared even between
    copies

Python's deep copy operation avoids these problems by:

 a) keeping a table of objects already copied during the current
    copying pass

 b) letting user-defined classes override the copying operation or the
    set of components copied

This version does not copy types like module, class, function, method,
nor stack trace, stack frame, nor file, socket, window, nor array, nor
any similar types.

Classes can use the same interfaces to control copying that they use
to control pickling: they can define methods called __getinitargs__(),
__getstate__() and __setstate__().  See the documentation for module
"pickle" for information on these methods.

Class Documentation

class copy::_EmptyClass

Definition at line 322 of file copy.py.


Function Documentation

def copy._copy_immutable (   x) [private]

Definition at line 102 of file copy.py.

00102 
00103 def _copy_immutable(x):
    return x
def copy._copy_with_constructor (   x) [private]

Definition at line 117 of file copy.py.

00117 
00118 def _copy_with_constructor(x):
    return type(x)(x)
def copy._copy_with_copy_method (   x) [private]

Definition at line 122 of file copy.py.

00122 
00123 def _copy_with_copy_method(x):
    return x.copy()
def copy._deepcopy_atomic (   x,
  memo 
) [private]

Definition at line 182 of file copy.py.

00182 
00183 def _deepcopy_atomic(x, memo):
00184     return x
00185 d[type(None)] = _deepcopy_atomic
00186 d[type(Ellipsis)] = _deepcopy_atomic
00187 d[int] = _deepcopy_atomic
00188 d[float] = _deepcopy_atomic
00189 d[bool] = _deepcopy_atomic
00190 try:
    d[complex] = _deepcopy_atomic

Here is the caller graph for this function:

def copy._deepcopy_dict (   x,
  memo 
) [private]

Definition at line 232 of file copy.py.

00232 
00233 def _deepcopy_dict(x, memo):
00234     y = {}
00235     memo[id(x)] = y
00236     for key, value in x.items():
00237         y[deepcopy(key, memo)] = deepcopy(value, memo)
00238     return y
d[dict] = _deepcopy_dict

Here is the call graph for this function:

def copy._deepcopy_list (   x,
  memo 
) [private]

Definition at line 205 of file copy.py.

00205 
00206 def _deepcopy_list(x, memo):
00207     y = []
00208     memo[id(x)] = y
00209     for a in x:
00210         y.append(deepcopy(a, memo))
00211     return y
00212 d[list] = _deepcopy_list

Here is the call graph for this function:

def copy._deepcopy_method (   x,
  memo 
) [private]

Definition at line 242 of file copy.py.

00242 
00243 def _deepcopy_method(x, memo): # Copy instance methods
00244     return type(x)(x.__func__, deepcopy(x.__self__, memo))
00245 _deepcopy_dispatch[types.MethodType] = _deepcopy_method

Here is the call graph for this function:

def copy._deepcopy_tuple (   x,
  memo 
) [private]

Definition at line 213 of file copy.py.

00213 
00214 def _deepcopy_tuple(x, memo):
00215     y = []
00216     for a in x:
00217         y.append(deepcopy(a, memo))
00218     d = id(x)
00219     try:
00220         return memo[d]
00221     except KeyError:
00222         pass
00223     for i in range(len(x)):
00224         if x[i] is not y[i]:
00225             y = tuple(y)
00226             break
00227     else:
00228         y = x
00229     memo[d] = y
00230     return y
00231 d[tuple] = _deepcopy_tuple

Here is the call graph for this function:

def copy._keep_alive (   x,
  memo 
) [private]
Keeps a reference to the object x in the memo.

Because we remember objects by their id, we have
to assure that possibly temporary objects are kept
alive by referencing them.
We store a reference at the id of the memo, which should
normally not be used unless someone tries to deepcopy
the memo itself...

Definition at line 246 of file copy.py.

00246 
00247 def _keep_alive(x, memo):
00248     """Keeps a reference to the object x in the memo.
00249 
00250     Because we remember objects by their id, we have
00251     to assure that possibly temporary objects are kept
00252     alive by referencing them.
00253     We store a reference at the id of the memo, which should
00254     normally not be used unless someone tries to deepcopy
00255     the memo itself...
00256     """
00257     try:
00258         memo[id(memo)].append(x)
00259     except KeyError:
00260         # aha, this is the first one :-)
00261         memo[id(memo)]=[x]

Here is the call graph for this function:

Here is the caller graph for this function:

def copy._reconstruct (   x,
  info,
  deep,
  memo = None 
) [private]

Definition at line 262 of file copy.py.

00262 
00263 def _reconstruct(x, info, deep, memo=None):
00264     if isinstance(info, str):
00265         return x
00266     assert isinstance(info, tuple)
00267     if memo is None:
00268         memo = {}
00269     n = len(info)
00270     assert n in (2, 3, 4, 5)
00271     callable, args = info[:2]
00272     if n > 2:
00273         state = info[2]
00274     else:
00275         state = {}
00276     if n > 3:
00277         listiter = info[3]
00278     else:
00279         listiter = None
00280     if n > 4:
00281         dictiter = info[4]
00282     else:
00283         dictiter = None
00284     if deep:
00285         args = deepcopy(args, memo)
00286     y = callable(*args)
00287     memo[id(x)] = y
00288 
00289     if state:
00290         if deep:
00291             state = deepcopy(state, memo)
00292         if hasattr(y, '__setstate__'):
00293             y.__setstate__(state)
00294         else:
00295             if isinstance(state, tuple) and len(state) == 2:
00296                 state, slotstate = state
00297             else:
00298                 slotstate = None
00299             if state is not None:
00300                 y.__dict__.update(state)
00301             if slotstate is not None:
00302                 for key, value in slotstate.items():
00303                     setattr(y, key, value)
00304 
00305     if listiter is not None:
00306         for item in listiter:
00307             if deep:
00308                 item = deepcopy(item, memo)
00309             y.append(item)
00310     if dictiter is not None:
00311         for key, value in dictiter:
00312             if deep:
00313                 key = deepcopy(key, memo)
00314                 value = deepcopy(value, memo)
00315             y[key] = value
00316     return y

Here is the call graph for this function:

Here is the caller graph for this function:

def copy._test ( ) [private]

Definition at line 325 of file copy.py.

00325 
00326 def _test():
00327     l = [None, 1, 2, 3.14, 'xyzzy', (1, 2), [3.14, 'abc'],
00328          {'abc': 'ABC'}, (), [], {}]
00329     l1 = copy(l)
00330     print(l1==l)
00331     l1 = map(copy, l)
00332     print(l1==l)
00333     l1 = deepcopy(l)
00334     print(l1==l)
00335     class C:
00336         def __init__(self, arg=None):
00337             self.a = 1
00338             self.arg = arg
00339             if __name__ == '__main__':
00340                 import sys
00341                 file = sys.argv[0]
00342             else:
00343                 file = __file__
00344             self.fp = open(file)
00345             self.fp.close()
00346         def __getstate__(self):
00347             return {'a': self.a, 'arg': self.arg}
00348         def __setstate__(self, state):
00349             for key, value in state.items():
00350                 setattr(self, key, value)
00351         def __deepcopy__(self, memo=None):
00352             new = self.__class__(deepcopy(self.arg, memo))
00353             new.a = self.a
00354             return new
00355     c = C('argument sketch')
00356     l.append(c)
00357     l2 = copy(l)
00358     print(l == l2)
00359     print(l)
00360     print(l2)
00361     l2 = deepcopy(l)
00362     print(l == l2)
00363     print(l)
00364     print(l2)
00365     l.append({l[1]: l, 'xyz': l[2]})
00366     l3 = copy(l)
00367     import reprlib
00368     print(map(reprlib.repr, l))
00369     print(map(reprlib.repr, l1))
00370     print(map(reprlib.repr, l2))
00371     print(map(reprlib.repr, l3))
00372     l3 = deepcopy(l)
00373     print(map(reprlib.repr, l))
00374     print(map(reprlib.repr, l1))
00375     print(map(reprlib.repr, l2))
00376     print(map(reprlib.repr, l3))
00377     class odict(dict):
00378         def __init__(self, d = {}):
00379             self.a = 99
00380             dict.__init__(self, d)
00381         def __setitem__(self, k, i):
00382             dict.__setitem__(self, k, i)
00383             self.a
00384     o = odict({"A" : "B"})
00385     x = deepcopy(o)
00386     print(o, x)

Here is the call graph for this function:

def copy.copy (   x)
Shallow copy operation on arbitrary Python objects.

See the module's __doc__ string for more info.

Definition at line 67 of file copy.py.

00067 
00068 def copy(x):
00069     """Shallow copy operation on arbitrary Python objects.
00070 
00071     See the module's __doc__ string for more info.
00072     """
00073 
00074     cls = type(x)
00075 
00076     copier = _copy_dispatch.get(cls)
00077     if copier:
00078         return copier(x)
00079 
00080     copier = getattr(cls, "__copy__", None)
00081     if copier:
00082         return copier(x)
00083 
00084     reductor = dispatch_table.get(cls)
00085     if reductor:
00086         rv = reductor(x)
00087     else:
00088         reductor = getattr(x, "__reduce_ex__", None)
00089         if reductor:
00090             rv = reductor(2)
00091         else:
00092             reductor = getattr(x, "__reduce__", None)
00093             if reductor:
00094                 rv = reductor()
00095             else:
00096                 raise Error("un(shallow)copyable object of type %s" % cls)
00097 
00098     return _reconstruct(x, rv, 0)
00099 

Here is the call graph for this function:

def copy.deepcopy (   x,
  memo = None,
  _nil = [] 
)
Deep copy operation on arbitrary Python objects.

See the module's __doc__ string for more info.

Definition at line 129 of file copy.py.

00129 
00130 def deepcopy(x, memo=None, _nil=[]):
00131     """Deep copy operation on arbitrary Python objects.
00132 
00133     See the module's __doc__ string for more info.
00134     """
00135 
00136     if memo is None:
00137         memo = {}
00138 
00139     d = id(x)
00140     y = memo.get(d, _nil)
00141     if y is not _nil:
00142         return y
00143 
00144     cls = type(x)
00145 
00146     copier = _deepcopy_dispatch.get(cls)
00147     if copier:
00148         y = copier(x, memo)
00149     else:
00150         try:
00151             issc = issubclass(cls, type)
00152         except TypeError: # cls is not a class (old Boost; see SF #502085)
00153             issc = 0
00154         if issc:
00155             y = _deepcopy_atomic(x, memo)
00156         else:
00157             copier = getattr(x, "__deepcopy__", None)
00158             if copier:
00159                 y = copier(memo)
00160             else:
00161                 reductor = dispatch_table.get(cls)
00162                 if reductor:
00163                     rv = reductor(x)
00164                 else:
00165                     reductor = getattr(x, "__reduce_ex__", None)
00166                     if reductor:
00167                         rv = reductor(2)
00168                     else:
00169                         reductor = getattr(x, "__reduce__", None)
00170                         if reductor:
00171                             rv = reductor()
00172                         else:
00173                             raise Error(
00174                                 "un(deep)copyable object of type %s" % cls)
00175                 y = _reconstruct(x, rv, 1, memo)
00176 
00177     memo[d] = y
00178     _keep_alive(x, memo) # Make sure x lives at least as long as d
00179     return y

Here is the call graph for this function:


Variable Documentation

list copy.__all__ = ["Error", "copy", "deepcopy"]

Definition at line 65 of file copy.py.

Definition at line 100 of file copy.py.

Definition at line 180 of file copy.py.

Definition at line 336 of file copy.py.

Definition at line 337 of file copy.py.

Definition at line 58 of file copy.py.

Definition at line 343 of file copy.py.

Definition at line 63 of file copy.py.

tuple copy.t = getattr(types, "CodeType", None)

Definition at line 109 of file copy.py.