【Python进阶】Python里如何拷贝一个对象

来源:互联网 发布:胸肌八字奶 知乎 编辑:程序博客网 时间:2024/06/05 23:52

1.  赋值:创建了一个对象的新引用,改变其中任意一个变量都会改变其他变量

2. 浅拷贝

(1)copy.copy(x)   浅拷贝其实就是用的切片操作

(2)完全切片法[:]

(3)工厂函数,如list()

注意:浅拷贝中,对于不可变对象,拷贝后等于新创建对象,id值各不相同,也就是说对于非容器类型,没有拷贝一说;对于可变对象,拷贝仅相当于新增一个引用,id值不变,对一个变量进行修改会影响到其余变量。

obj = ['name',['age',18]]a=obj[:]b=list(obj) for x in obj,a,b:    print id(x[0]),id(x[1])print a[0] = 'lisi'b[0] = 'zhangsan' for x in obj,a,b:    print id(x[0]),id(x[1])print a[1][1] = 25b[1][1] = 30 for x in obj,a,b:    print(id(x[0]),id(x[1]) 输出:32564088 3449600832564088 3449600832564088 34496008 32564088 3449600834574704 3449600833970672 34496008 32564088 3449600834574704 3449600833970672 34496008


3. 深拷贝

copy.deepcopy(x, memo=None, _nil=[])

注意:如果元组变量只包括原子对象,对它的深拷贝将不被进行。深拷贝之后id值不会变。

# encoding=UTF-8import copyobj = ['name',('age',18)]a=copy.deepcopy(obj)b=copy.deepcopy(obj) for x in a,b:    print(id(x[0]),id(x[1])print 输出:34703752 3469300034756616 34693000


copy模块的说明:

    
            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.

    copy(x)
        Shallow copy operation on arbitrary Python objects.
    
    deepcopy(x, memo=None, _nil=[])
        Deep copy operation on arbitrary Python objects.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.


例1.

import copy  list1 = ['a','b','c',['d','e']] list2 = copy.copy(list1) list3 = copy.deepcopy(list1)  list1.append('f') list1[3].append('x')  print list1 print list2 print list3  list4 = list1 print list4 结果: ['a', 'b', 'c', ['d', 'e', 'x'], 'f']['a', 'b', 'c', ['d', 'e', 'x']]['a', 'b', 'c', ['d', 'e']]['a', 'b', 'c', ['d', 'e', 'x'], 'f']

以list为例,如果是浅拷贝,系统就新建一个列表,像C里的指针数组一样,它的每一个元素都指向原来列表的每一个元素,输出时就将新列表里各个元素所指向的内容显示出来。所以list1追加了元素f后list2并没有显示,因为list2里没有指向这个新元素的元素。但list1[2]追加了x后显示出来了,因为在list2中对list1[2]有对应的指向,能显示。

而深拷贝是新建一个列表将原列表里的内容原封不动地搬过来,至于之后原列表做了什么改变根本不关新列表的事,二者是两个不同的引用指向两个不同的对象。

浅拷贝是对引用的拷贝,是活的,深拷贝是对资源的拷贝,是死的。

赋值操作则是两个引用指向同一个对象,当然改变其中一个会改变另一个。


0 0