您的位置:首页 > 编程语言 > Python开发

【python】深浅拷贝

2017-12-11 21:46 411 查看
在python中一切都是对象

print(type(1))
print(type("Hello World"))
print(type(["A","B","C"]))

>>> <class 'int'>
>>> <class 'str'>
>>> <class 'list'>


甚至连type本身都是对象,type对象

print(type(type(["A","B","C"])))

>>> <class 'type'>


变量引用

python是动态类型,程序运行时候,会根据对象的类型来确认变量到底是什么类型

比如
a = 3
,在运行后变量a变成了变量3的一个引用,在内部,变量事实上是对对象内存空间的一个指针



变量 :一个系统表的元素,拥有指向对象的连接的空间

对象 :被分配的一块内存,存储其所代表的值

引用 :自动形成的从变量到对象的指针

共享引用

a = 3
b = a


在运行赋值语句b = a之后,变量a和变量b指向了同一个对象的内存空间



    a = 3
b = a
print(id(a))
print(id(b))

>>> 1749726336
>>> 1749726336


a和b的id完全一样,指向同一个整数对象3,或者说同一块内存

    a = 3
b = a
a = "sss"
print(a)
print(b)

>>> sss
>>> 3


可变对象&不可变对象

不可变对象: 一旦创建就不可修改的对象,包括字符串,元祖,数字

可变对象:可以修改的对象,包括:列表、字典

上面的a,b为整数或字符串,是不可变对象,若是可变对象,则会出现什么样的情况呢?

a = [1,2,3]
b = a
a[0] = 100
print(a)
print(b)

>>> [100, 2, 3]
>>> [100, 2, 3]


修改 b 的值同时也会改变a的值

a = [1,2,3]
b = a
a[0] = 100
b[1] = 200
print(a)
print(b)

>>> [100, 200, 3]
>>> [100, 200, 3]


在使用python赋值时,就碰到了一个坑,同时指向一个可变对象,导致了调用的变量为修改后的值

如果不想改变可变变量的值,有两种方法,切片和copy模块

切片

a = [1,2,3]
b = a[:]
a[0] = 100
b[1] = 200
print(a)
print(b)

>>> [100, 2, 3]
>>> [1, 200, 3]


切片技术应用于所有序列,包括:列表、字符串

但切片不能应用于字典,对字典只能使用D.copy() 或 D.deepcopy() 方法

a = {"name":"llz","id":88}
b = a[:]

>>>Traceback (most recent call last):
File "xxx.py", line 96, in <module>
b = a[:]
TypeError: unhashable type: 'slice'


拷贝

拷贝既可用于序列,也可以用于字典

import copy
b = {"name":"llz","id":8}
a = copy.copy(b)      #浅拷贝:只拷贝顶级的对象,或者说:父级对象
a = copy.deepcopy(b)  #深拷贝:拷贝所有对象,顶级对象及其嵌套对象。或者说:父级对象及其子对象


字典只有顶级对象

import copy
a = {"executeType": 1,"data": "seewo"}
a1 = copy.copy(a)         # 浅拷贝对象
a2 = copy.deepcopy(a)     # 深拷贝对象
print(a)
print(a1)
print(a2)

>>> {'executeType': 1, 'data': 'seewo'}
>>> {'executeType': 1, 'data': 'seewo'}
>>> {'executeType': 1, 'data': 'seewo'}

print(id(a),id(a1),id(a2))    # 可以看出内存空间对象不一样

>>> 56795568 56797296 56797368

a["executeType"]= "cc"
print(a)
print(a1)
print(a2)

>>> {'executeType': 'cc', 'data': 'seewo'}
>>> {'executeType': 1, 'data': 'seewo'}
>>> {'executeType': 1, 'data': 'seewo'}

a改变了,深和浅拷贝均没变


字典中有嵌套对象

import copy
a = {"executeType": [1,2],"data": {"Code": "seewo", "interfaceId": "5", "caseID": "1"}}
a1 = copy.copy(a)         # 浅拷贝对象
a2 = copy.deepcopy(a)     # 深拷贝对象
print(a)
print(a1)
print(a2)

>>> {'executeType': [1, 2], 'data': {'Code': 'seewo', 'interfaceId': '5', 'caseID': '1'}}
>>> {'executeType': [1, 2], 'data': {'Code': 'seewo', 'interfaceId': '5', 'caseID': '1'}}
>>> {'executeType': [1, 2], 'data': {'Code': 'seewo', 'interfaceId': '5', 'caseID': '1'}}

print(id(a),id(a1),id(a2))    # 可以看出内存空间对象不一样

>>>56731832 56731976 56732480

a["executeType"][0] = "cc"
print(a)
print(a1)
print(a2)

>>> {'executeType': ['cc', 2], 'data': {'Code': 'seewo', 'interfaceId': '5', 'caseID': '1'}}
>>> {'executeType': ['cc', 2], 'data': {'Code': 'seewo', 'interfaceId': '5', 'caseID': '1'}}
>>> {'executeType': [1, 2], 'data': {'Code': 'seewo', 'interfaceId': '5', 'caseID': '1'}}


深浅拷贝都是对源对象的复制,占用不同的内存空间

如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象

如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝

序列对象的切片其实是浅拷贝,即只拷贝顶级的对象
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 对象 拷贝