欢迎访问 生活随笔!

凯发ag旗舰厅登录网址下载

当前位置: 凯发ag旗舰厅登录网址下载 > 编程语言 > >内容正文

python

python中浅拷贝与深拷贝 -凯发ag旗舰厅登录网址下载

发布时间:2025/1/21 18 豆豆
凯发ag旗舰厅登录网址下载 收集整理的这篇文章主要介绍了 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

参考链接
1. 引用 https://blog.csdn.net/qq_38556217/article/details/103002827
2. python中变量在内存的存储与地址变化详解(深浅拷贝,值/引用传递、可变不可变数据类型)
3. python深拷贝和浅拷贝的区别

首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别

一、可变对象与不可变对象

  • 可变对象:当有需要改变对象的值的时候,这个对象的id不发生变化(不超过存储空间的情况)。可变类型数据:列表、集合、字典、对象
  • 不可变对象:当有需要改变对象的值的时候,这个对象的id会发生变化。不可变类型数据:数值、字符串、布尔、元组
    3.id()获取对象的内存地址
  • python地址存储特殊性,使用固定内存地址存储数据如下:
    -5到256的整数、true和false、由字母、数字、下滑线组成的字符串
  • 二、对可变对此的操作是否新建对象?

    这里以列表为例,实验对列表的操作,是否改变了列表对象,及id(列表对象)是否发生了变化。

    2.1 不改变id(列表对象)的操作

    • append()方法
    • = 连接列表
    • 删除某个元素 del l[1]
    • 改变某个元素的值 l[2]=10

    2.2 改变id(列表对象)的操作

    * 切片操作,`a[:2]`,及全部复制`a[:]` * 连接列表 `a = a [...]`

    三、赋值、浅拷贝与深拷贝

    python 中赋值语句不复制对象,而是在目标和对象之间创建绑定 (bindings) 关系。

    3.1 赋值操作=

    相当于复制一个引用,指向同一个内存地址。改变其中一个变量的值,

    • 如果是可变对象,其余的也会跟着变。它们之间的id值相同
    • 如果是不可变对象,改变其中一个变量的值相当于新建一个对象,它们之间的id值不同

    3.2 浅拷贝

    浅拷贝会新建一个对象,拷贝对象与元对象的变化间有无关联,要看元对象中的元素类型

  • 被拷贝的对象中是否包含可变对象
    • 不包含。拷贝后对象变化与原对象间没有关系
    • 包含。可变对象的变化会同时发生在原对象和拷贝对象中。

    拷贝的对象中,包含可变对象时,新对象中保存的是可变对象的地址。

    3.3 深拷贝

    拷贝后,拷贝后对象变化与原对象间没有关系

    浅拷贝与深拷贝的区别,总的来说就是拷贝一层和多层的区别
    深拷贝操作通常存在两个问题, 而浅拷贝操作并不存在这些问题:

    • 递归对象 (直接或间接包含对自身引用的复合对象) 可能会导致递归循环。
    • 由于深拷贝会复制所有内容,因此可能会过多复制(例如本应该在副本之间共享的数据)。

    四、引用传递与值传递

    可变对象为引用传递,不可变对象为值传递。(函数传值)

    1,值传递: 简单来说 对于函数输入的参数对象,函数执行中首先生成对象的一个副本,并在执行过程中对副本进行操作。执行结束后对象不发生改变
    即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。(被调函数新开辟内存空间存放的是实参的副本值)

    值传递不会改变原来函数的值,

    def change(b):b = 2 传递进来的为不可变对象,为值传递 相当于相同值的一个副本print(id(b)) print (b)returna = 2 print(id(a)) change(a) print (a) print(id(a))

    输出为

    140724617470832 a本来地址 140724617470896 值传递b的地址 4 在函数中为4 2 a本身还是2 140724617470832 a地址也没有改变

    4.2. 引用传递

    当传递列表或者字典时,如果改变引用的值,就修改了原始的对象。(被调函数新开辟内存空间存放的是实参的地址)

    def change(str1):str1[1] ="changed " 此处修改就是直接修改string的值returnstring = ['hello world',2,3] print (string) change(string) print (string)

    函数的实参使用可变类型数据时,在函数内部对形参进行数据操作,实参将发生改变
    函数的实参使用不可变类型数据时,在函数内部对形参进行数据操作,实参将不会发生改变

    总结

    以上是凯发ag旗舰厅登录网址下载为你收集整理的的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得凯发ag旗舰厅登录网址下载网站内容还不错,欢迎将凯发ag旗舰厅登录网址下载推荐给好友。

    • 上一篇:
    • 下一篇:
    网站地图