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

  • 利用切片操作和工厂方法list方法拷贝
  • 利用copy中的deepcopy方法进行拷贝

1、利用切片操作和工厂方法list方法拷贝

代码场景:有一个小伙jack,tom通过切片操作拷贝jack,anny通过工厂方法拷贝jack。

>>> jack = ['jack', ['age', 20]]
>>> tom = jack[:]
>>> anny = list(jack)

来看下三者的id值:

>>> print id(jack), id(tom), id(anny)
144846988 144977164 144977388

从id值来看,三者是不同的对象。为tom和anny重新命名为各自的名称:

>>> tom[0] = 'tom'
>>> anny[0] = 'anny'
>>> print jack, tom, anny
['jack', ['age', 20]] ['tom', ['age', 20]] ['anny', ['age', 20]]

从这里来看一切正常,可是anny只有18岁,重新为anny定义岁数。

>>> anny[1][1] = 18
>>> print jack, tom, anny
['jack', ['age', 18]] ['tom', ['age', 18]] ['anny', ['age', 18]]

这时候奇怪的事情发生了,jack、tom、anny的岁数都发生了改变,都变成了18了。jack、tom、anny他们应当都是不同的对象,怎么会互相影响呢?看下jack,tom,anny的内部元素每个元素id:

>>> [id(x) for x in jack]
[3073896320L, 3073777580L]
>>> [id(x) for x in tom]
[144870744, 3073777580L]
>>> [id(x) for x in anny]
[144977344, 3073777580L]

恍然大悟,原来jack、tom、anny的岁数元素指向的是同一个元素。修改了其中一个,当然影响其他人了。那为什么修改名称没影响呢?原来在python中字符串不可以修改,所以在为tom和anny重新命名的时候,会重新创建一个’tom’和’anny’对象,替换旧的’jack’对象。为了便于理解,我画了一个草图:

python浅拷贝图解

2、利用copy中的deepcopy方法进行拷贝

为了让他们之间不互相影响,用deepcopy来试试

>>> jack = ['jack', ['age', '20']]
>>> import copy
>>> tom = copy.deepcopy(jack)
>>> anny = copy.deepcopy(jack)

根据第一个思路进行重命名,重定岁数操作:

>>> tom[0] = 'tom'
>>> anny[0] = 'anny'
>>> print jack, tom, anny
['jack', ['age', '20']] ['tom', ['age', '20']] ['anny', ['age', '20']]
>>> anny[1][1] = 18
>>> print jack, tom, anny
['jack', ['age', '20']] ['tom', ['age', '20']] ['anny', ['age', 18]]

这时候他们之间就不会互相影响了。打印出每个人的内部元素每个id:

>>> [id(x) for x in jack]
[139132064, 3073507244L]
>>> [id(x) for x in tom]
[139137464, 139132204]
>>> [id(x) for x in anny]
[139141632, 139157548]

他们的内部元素也都指向了不同的对象。

小结:

思路一:利用切片操作和工厂方法list方法拷贝就叫浅拷贝,只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。

思路二:利用copy中的deepcopy方法进行拷贝就叫做深拷贝,外围和内部元素都进行了拷贝对象本身,而不是引用。

但是对于数字,字符串和其他原子类型对象等,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。

python中的深拷贝和浅拷贝理解的更多相关文章

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

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

  2. 001 说说Python中的深拷贝和浅拷贝

    在Python编程中忽略深拷贝和浅拷贝可能会造成未知的风险. 比如我们打算保存一份原始对象的副本作为上一状态的记录,此后修改原始对象数据时,若是副本对象的数据也发生改变,那么这就是一个严重的错误. 注 ...

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

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

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

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

  5. Python 中的深拷贝和浅拷贝

    一.浅拷贝python中 对象赋值时 默认是浅拷贝,满足如下规律:1. 对于 不可变对象(字符串,元组 等),赋值 实际上是创建一个新的对象:例如: >>> person=['nam ...

  6. python中的深拷贝和浅拷贝(面试题二)

    一.浅拷贝 定义:浅拷贝只是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值. 浅拷贝的特点: 公用一个值: 这两个变量的内存地址一样: 对其中一个变量的值改变,另外一个变量的值也 ...

  7. python中的深拷贝和浅拷贝(面试题)

    一.浅拷贝 定义:浅拷贝只是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值. 浅拷贝的特点: 公用一个值: 这两个变量的内存地址一样: 对其中一个变量的值改变,另外一个变量的值也 ...

  8. 【转】Python中的赋值、浅拷贝、深拷贝介绍

    这篇文章主要介绍了Python中的赋值.浅拷贝.深拷贝介绍,Python中也分为简单赋值.浅拷贝.深拷贝这几种"拷贝"方式,需要的朋友可以参考下   和很多语言一样,Python中 ...

  9. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

随机推荐

  1. F12调试模式下使用console自动提交

    F12调试模式下使用console自动提交(F12 的console->输入代码->按enter即可运行) 1.使用定时器setInterval进行自动提交 //方法中可使用jquery调 ...

  2. 【SqlServer】JSON函数

    1   概述 本篇文件将结合MSND简要分析Sqlserver中JSON函数,主要包括ISJSON,JSON_VALUE,JSON_MODIFY,JSON_QUERY. 2   具体内容 2.1  J ...

  3. 关于一些常用的linux命令

    作为一个程序员了解linux系统还是很必要的,下面我为大家提供一些linux系统中比较常的命令 一.linux系统命令 1.Cd  进入指定目录 2.ls 显示当前目录下的文件 3.ls-a 显示所有 ...

  4. 获取本地ip

    public void GetLocalIP(string username) { List<string> strIPs = new List<string>(); Netw ...

  5. Bandit Wargame Level24 Writeup(brute-forcing with shell)

    Bandit Level 24 → Level 25 Level Goal A daemon is listening on port 30002 and will give you the pass ...

  6. selenium.common.exceptions.WebDriverException: Message: 'phantomjs' executab

    该问题博主是在Mac环境遇到的,对应windows找对应解决方案解决即可. 问题原因: phantomjs环境配置有问题,要么是配置错误,要么是没有配置. 解决方案: 1.将下载解压好的phantom ...

  7. 快看Sample代码,速学Swift语言(2)-基础介绍

    Swift语言是一个新的编程语言,用于iOS, macOS, watchOS, 和 tvOS的开发,不过Swift很多部分内容,我们可以从C或者Objective-C的开发经验获得一种熟悉感.Swif ...

  8. 接口json数据与数据库数据循环比对校验

    创建测试计划,加载数据库驱动: 线程组: csv配置元件: 注:Filename用的是相对路径,csv文件要与jmeter脚本文件在同一目录 JDBC连接配置: jdbc请求: 用户定义的变量: ht ...

  9. [Maven] Missing artifact

    今天从朋友那拷过来一个maven工程,eclipse中maven配置好了,maven仓库也配置完毕,但是一直报Missing artifact,然后开网执行maven update,下载完jar后,还 ...

  10. 免费SSL&付费SSL证书,该如何选择?

    近年来Google.Apple.百度等公司不断推动 HTTPS 的普及,SSL 证书作为 HTTPS 安全协议的必备配置,自然也成为了网站.App 开发者最重要部署项目之一. 又拍云于 2016 年联 ...