copy -- Duplicate objects

https://www.safaribooksonline.com/library/view/python-cookbook-2nd/0596007973/ch04s02.html

Discussion

When you assign an object (or pass it as an argument, or return it as a result), Python (like Java) uses a reference to the original object, not a copy. Some other programming languages make copies every time you assign something. Python never makes copies "implicitly" just because you're assigning: to get a copy, you must specifically request a copy.

Python's behavior is simple, fast, and uniform. However, if you do need a copy and do not ask for one, you may have problems. For example:

>>> a = [1, 2, 3]
>>> b = a
>>> b.append(5)
>>> print a, b[1, 2, 3, 5] [1, 2, 3, 5]

Here, the names a and b both refer to the same object (a list), so once we alter the object through one of these names, we later see the altered object no matter which name we use for it. No original, unaltered copy is left lying about anywhere.

WARNING
To become an effective Python programmer, it is crucial that you learn to draw the distinction between altering an object and assigning to a name, which previously happened to refer to the object. These two kinds of operations have nothing to do with each other. A statement such as a=[ ] rebinds name a but performs no alteration at all on the object that was previously bound to name a. Therefore, the issue of references versus copies just doesn't arise in this case: the issue is meaningful only when you alter some object.

Shallow Copies

The shallow copy created by copy() is a new container populated with references to the contents of the original object. For example, a new list is constructed and the elements of the original list are appended to it.

import copy

class MyClass:
    def __init__(self, name):
        self.name = name
    def __cmp__(self, other):
        return cmp(self.name, other.name)

a = MyClass('a')
l = [ a ]
dup = copy.copy(l)

print 'l  :', l
print 'dup:', dup
print 'dup is l:', (dup is l)
print 'dup == l:', (dup == l)
print 'dup[0] is l[0]:', (dup[0] is l[0])
print 'dup[0] == l[0]:', (dup[0] == l[0])

For a shallow copy, the MyClass instance is not duplicated so the reference in the dup list is to the same object that is in the l list.

l  : [<__main__.MyClass instance at 0x100467d88>]
dup: [<__main__.MyClass instance at 0x100467d88>]
dup is l: False
dup == l: True
dup[0] is l[0]: True
dup[0] == l[0]: True

Deep Copies

The deep copy created by deepcopy() is a new container populated with copies of the contents of the original object. For example, a new list is constructed and the elements of the original list are copied, then the copies are appended to the new list.

By replacing the call to copy() with deepcopy(), the difference becomes apparent.

dup = copy.deepcopy(l)

Notice that the first element of the list is no longer the same object reference, but the two objects still evaluate as being equal.

l  : [<__main__.MyClass instance at 0x100467d88>]
dup: [<__main__.MyClass instance at 0x100467dd0>]
dup is l: False
dup == l: True
dup[0] is l[0]: False
dup[0] == l[0]: True

你可能感兴趣的:(copy -- Duplicate objects)