感谢前辈:学习连接

总结:

本文介绍了对象的赋值和拷贝,以及它们之间的差异:

  • Python中对象的赋值都是进行对象引用(内存地址)传递
  • 使用copy.copy(),可以进行对象的浅拷贝,它复制了对象,但对于对象中的元素,依然使用原始的引用.
  • 如果需要复制一个容器对象,以及它里面的所有元素(包含元素的子元素),可以使用copy.deepcopy()进行深拷贝
  • 对于非容器类型(如数字、字符串、和其他'原子'类型的对象)没有被拷贝一说
  • 如果元祖变量只包含原子类型对象,则不能深拷贝,看下面的例子

 

图片总结:

python深拷贝构造函 python对象深拷贝_c#

python深拷贝构造函 python对象深拷贝_深拷贝_02

python深拷贝构造函 python对象深拷贝_c#_03

注意上面深拷贝中,39774408的wiber中,"will", "28"地址不变,因为他们是原子类型,没有拷贝一说,但是其中的list,很明显深拷贝的中的["Python", "C#", "JavaScript"]对象,在新的地址空间中整个复制了一块,跟原来没关系了。

代码:

# @TIME : 2019/3/30 下午2:14
# @File : 浅拷贝-深拷贝.py



# 对象赋值操作!
print('--对象赋值操作--\n')
will = ["will", 28, ["python", "c#", "JavaScript"]]

wilber = will


print("will的id是",id(will))
print("wilber的id是",id(wilber))
print("will 中元素 id: ", [id(i) for i in will])
print("wilber 中元素 id: ", [id(i) for i in wilber])
print("will  = ", will)
print("wilber = ", wilber)


# 修改元素
will[0] = "HAHA"     #这里需要注意的一点是,str是不可变类型,所以当修改的时候会替换旧的对象
will[2].append("C++")
print('-----------------------------------------------------\n')

print("will的id是",id(will))
print("wilber的id是",id(wilber))
print("will 中元素 id: ", [id(i) for i in will])
print("wilber 中元素 id: ", [id(i) for i in wilber])
print("will  = ", will)
print("wilber = ", wilber)






# 浅拷贝
print("\n--浅拷贝--\n")

import copy

a = ["will", 28, ['python', 'c#', 'JavaScript']]
b = copy.copy(a)
print("a的id是",id(a))
print("b的id是",id(b))
print("a 中元素 id: ", [id(i) for i in a])
print("b 中元素 id: ", [id(i) for i in b])
print("a  = ", a)
print("b = ", b)

a[0] = 'haha'
a[2].append('c++')
print('-----------------------------------------------------\n')
print("a的id是",id(a))
print("b的id是",id(b))
print("a 中元素 id: ", [id(i) for i in a])
print("b 中元素 id: ", [id(i) for i in b])
print("a  = ", a)
print("b = ", b)


# 总结一下,当我们使用下面的操作的时候,会产生浅拷贝的效果:
#
# 使用切片[:]操作
# 使用工厂函数(如list/dir/set)
# 使用copy模块中的copy()函数




# 深拷贝
print("\n--深拷贝--\n")
a = ["will", 28, ['python', 'c#', 'JavaScript']]
b = copy.deepcopy(a)
print("a的id是",id(a))
print("b的id是",id(b))
print("a 中元素 id: ", [id(i) for i in a])
print("b 中元素 id: ", [id(i) for i in b])
print("a  = ", a)
print("b = ", b)

a[0] = 'haha'
a[2].append('c++')
print('-----------------------------------------------------\n')
print("a的id是",id(a))
print("b的id是",id(b))
print("a 中元素 id: ", [id(i) for i in a])
print("b 中元素 id: ", [id(i) for i in b])
print("a  = ", a)
print("b = ", b)


# 其实,对于拷贝有一些特殊情况:
#
# 对于非容器类型(如数字、字符串、和其他'原子'类型的对象)没有拷贝这一说
# 也就是说,对于这些类型,"obj is copy.copy(obj)" 、"obj is copy.deepcopy(obj)"
# 如果元祖变量只包含原子类型对象,则不能深拷贝,看下面的例子

 

结果:

--对象赋值操作--

will的id是 4559779080
wilber的id是 4559779080
will 中元素 id:  [4433642920, 4431481632, 4559689416]
wilber 中元素 id:  [4433642920, 4431481632, 4559689416]
will  =  ['will', 28, ['python', 'c#', 'JavaScript']]
wilber =  ['will', 28, ['python', 'c#', 'JavaScript']]
-----------------------------------------------------

will的id是 4559779080
wilber的id是 4559779080
will 中元素 id:  [4439464848, 4431481632, 4559689416]
wilber 中元素 id:  [4439464848, 4431481632, 4559689416]
will  =  ['HAHA', 28, ['python', 'c#', 'JavaScript', 'C++']]
wilber =  ['HAHA', 28, ['python', 'c#', 'JavaScript', 'C++']]

--浅拷贝--

a的id是 4559783240
b的id是 4559783176
a 中元素 id:  [4433642920, 4431481632, 4559783304]
b 中元素 id:  [4433642920, 4431481632, 4559783304]
a  =  ['will', 28, ['python', 'c#', 'JavaScript']]
b =  ['will', 28, ['python', 'c#', 'JavaScript']]
-----------------------------------------------------

a的id是 4559783240
b的id是 4559783176
a 中元素 id:  [4439502496, 4431481632, 4559783304]
b 中元素 id:  [4433642920, 4431481632, 4559783304]
a  =  ['haha', 28, ['python', 'c#', 'JavaScript', 'c++']]
b =  ['will', 28, ['python', 'c#', 'JavaScript', 'c++']]

--深拷贝--

a的id是 4559783048
b的id是 4559783240
a 中元素 id:  [4433642920, 4431481632, 4559783112]
b 中元素 id:  [4433642920, 4431481632, 4559782472]
a  =  ['will', 28, ['python', 'c#', 'JavaScript']]
b =  ['will', 28, ['python', 'c#', 'JavaScript']]
-----------------------------------------------------

a的id是 4559783048
b的id是 4559783240
a 中元素 id:  [4439502496, 4431481632, 4559783112]
b 中元素 id:  [4433642920, 4431481632, 4559782472]
a  =  ['haha', 28, ['python', 'c#', 'JavaScript', 'c++']]
b =  ['will', 28, ['python', 'c#', 'JavaScript']]

Process finished with exit code 0