1. 对象赋值

对象的赋值实际上是对对象的引用。也就是说当把一个对象赋值给另一个对象时,只是拷贝了引用。如:

>>> t1 = tuple('furzoom')
>>> t2 = t1
>>> id(t1),id(t2)
(139792198303936, 139792198303936)

上面t1和t2代表的是同一个对象。

2. 浅拷贝

除了上面将一个对象直接赋值给另一个对象外,还有两种常用的方法对对象进行拷贝:使用切片操作和工厂方法。

>>> car = ['grand', ['length', 4.85]]
>>> a4 = car[:]
>>> a6 = list(car)
>>> [hex(id(x)) for x in car, a4, a6]
['0x7f23e84da2d8', '0x7f23e84da128', '0x7f23e84da3f8']

通过创建汽车a4和a6,确实表示是不同的对象。现在继续完善a4和a6,修改它们的名字,和汽车长度。

>>> a4[0] = 'a4'
>>> a6[0] = 'a6'
>>> a4, a6
(['a4', ['length', 4.85]], ['a6', ['length', 4.85]])
>>> a4[1][1] = 4.761
>>> a4, a6
(['a4', ['length', 4.761]], ['a6', ['length', 4.761]])

修改汽车名字时,他们表现是正常的,而修改汽车车长时,发生了不期望的结果,修改a4的长度,同时也影响了a6的长度。

为什么会这样呢?原因在于只是针对序列做了浅拷贝。序列类型对象的浅拷贝是默认的拷贝,体现在:使用切片操作[:]、工厂函数、copy模块的copy函数。当改变a6汽车名字时,为什么没有体现在a4汽车上呢?这是因为名字是字符串类型,它是一个不可变类型,改变其内容将引用新建的对象。如下:

>>> a8 = list(car)
>>> [hex(id(x)) for x in car]
['0x7f23e84d7a80', '0x7f23e84da320']
>>> [hex(id(x)) for x in a8]
['0x7f23e84d7a80', '0x7f23e84da320']
>>> [hex(id(x)) for x in a4]
['0x7f23e84d4d78', '0x7f23e84da320']
>>> [hex(id(x)) for x in a6]
['0x7f23e84d4e40', '0x7f23e84da320']

在a4和a6的第二项,它们引用的是同一个对象。

3. 深拷贝

要想避免上面的这种影响,需要对列表进行深拷贝。需要使用copy模块的deepcopy()函数。

如:

>>> car = ['grand', ['length', 4.85]]
>>> a4 = car
>>> import copy
>>> a6 = copy.deepcopy(car)
>>> [hex(id(x)) for x in car, a4, a6]
['0x7f23e84da098', '0x7f23e84da098', '0x7f23e84da440']
>>> a4[0] = 'a4'
>>> a6[0] = 'a6'
>>> a4,a6
(['a4', ['length', 4.85]], ['a6', ['length', 4.85]])
>>> a4[1][1] = 4.761
>>> a4,a6
(['a4', ['length', 4.761]], ['a6', ['length', 4.85]])

另,在copy模块中,只有两个函数,copydeepcopy

Python对象拷贝——深拷贝与浅拷贝的更多相关文章

  1. Python 对象的深拷贝与浅拷贝 -- (转)

    本文内容是在<Python核心编程2>上看到的,感觉很有用便写出来,给大家参考参考! 浅拷贝 首先我们使用两种方式来拷贝对象,一种是切片,另外一种是工厂方法.然后使用id函数来看看它们的标 ...

  2. **Python中的深拷贝和浅拷贝详解

    Python中的深拷贝和浅拷贝详解   这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容.   要说清楚Python中的深浅拷贝,需要 ...

  3. Python赋值语句与深拷贝、浅拷贝的区别

    参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...

  4. java 复制Map对象(深拷贝与浅拷贝)

      java 复制Map对象(深拷贝与浅拷贝) CreationTime--2018年6月4日10点00分 Author:Marydon 1.深拷贝与浅拷贝 浅拷贝:只复制对象的引用,两个引用仍然指向 ...

  5. 谈谈java中对象的深拷贝与浅拷贝

    知识点:java中关于Object.clone方法,对象的深拷贝与浅拷贝 引言: 在一些场景中,我们需要获取到一个对象的拷贝,这时候就可以用java中的Object.clone方法进行对象的复制,得到 ...

  6. python中的深拷贝与浅拷贝

    深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...

  7. 浅谈python 复制(深拷贝,浅拷贝)

    博客参考:点击这里 python中对象的复制以及浅拷贝,深拷贝是存在差异的,这儿我们主要以可变变量来演示,不可变变量则不存在赋值/拷贝上的问题(下文会有解释),具体差异如下文所示 1.赋值: a=[1 ...

  8. python中的深拷贝和浅拷贝理解

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用.以下分两个思路来分别理解浅拷贝和深拷贝: 利用切 ...

  9. python中的深拷贝和浅拷贝

    python的复制,深拷贝和浅拷贝的区别   在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...

随机推荐

  1. Python的格式化输出,基本运算符,编码

    一. 格式化输出现在有以下需求,让用户输入name, age, job,hobby 然后输出如下所示: -----------info of Alex Li----------- Name : Ale ...

  2. est6 -- Object.is()、Object.assign()、Object.defineProperty()、Symbol、Proxy

    Object.is()用来比较两个值是否严格相等.它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身. + === - //true NaN === ...

  3. 饼系列—圈饼 doughnut

    chartControl属性 ApplicationSettings: Name:控件名字 AccessibleDescription: ??? AccessibleName:??? Accessib ...

  4. python装饰器的深度探究

    1.讲装饰器一般讲到这种代码就可以了,但这篇博客会介绍更多: def deco(func): def wrapper(): print("start") func() #调用函数 ...

  5. BT种子文件文件结构分析(转)

    估计80%以上接触互联网的人都知道bt是什么东西,任何一个用bt下载的人都知道这样一个概念,种子.bt种子就是记录了p2p对等网络中tracker, nodes, files等信息,也就是说,这个种子 ...

  6. codeforces 553 D Nudist Beach

    题意大概是.给出一个图,保证每一个点至少有一条边以及随意两点间最多一条边.非常显然这个图有众多点集,若我们给每一个点定义一个权值,那每一个点集都有一个最小权值点,如今要求出一个点集,这个点集的最小权值 ...

  7. python的多线程问题

    在对文件进行预处理的时候,由于有的文件有太大,处理很慢,用python处理是先分割文件,然后每个文件起一个线程处理,启了10个线程,结果还比不起线程慢一些,改成多进程之后就好了. 使用multipro ...

  8. 【Sprint3冲刺之前】敏捷团队绩效考核(刘铸辉)

     TD学生助手团队已经在4.22~4.30完成了为期9天的Sprint2计划,并在Sprint2总结会议中安排了五一放假每个人的任务分配,下面发布下Sprint2冲刺周期的阶段性成果. Sprint2 ...

  9. 轻松搞定RabbitMQ(二)——工作队列之消息分发机制

    转自 http://blog.csdn.net/xiaoxian8023/article/details/48681987 上一篇博文中简单介绍了一下RabbitMQ的基础知识,并写了一个经典语言入门 ...

  10. Java泛型 类型变量的限定

    有时候,类和方法须要对类型变量加以约束.比方你有一个方法,你仅仅希望它接收某个特定类型及其子类型作为參数. 以下就举一个方法限定接收參数的类型的样例来说明怎样限定类型变量. 首先有几个简单的辅助类: ...