Python数据传递与内存开销
本文探讨Python变量在赋值、传参、深浅拷贝时,通过观察变量
id
是否改变,得知是否会发生另外的内存开销
1. 赋值运算符
# 指针(复制地址)
x=1
print(id(x))
y=x
print(id(y))
2056219879728
2056219879728
# 指针(复制地址)
x=[1,2]
print(id(x))
y=x
print(id(y))
2056301222336
2056301222336
2. 函数参数传递与结果返回
- P y t h o n Python Python传参与返回结果默认都是用指针
def hello(obj):
return obj
x=1
print(id(x))
y=hello(x)
print(id(y))
2056219879728
2056219879728
3. 构造
构造的实质是调用构造函数, 所以传递数据用的都是指针
- 内外均为不可变对象
a,b='hjd','zyy'
print(id(a),id(b))
x=(a,b)
print(id(x[0]),id(x[1]))
2056301519088 2056301522160
2056301519088 2056301522160
- 内为可变, 外为不可变
a, b = [1], [2]
print(id(a), id(b))
x = (a, b)
print(id(x[0]), id(x[1]))
2056300472384 2056301583616
2056300472384 2056301583616
- 内为不可变, 外为可变
a, b = 'hjd', 'zyy'
print(id(a), id(b))
x = [a, b]
print(id(x[0]), id(x[1]))
2056301522032 2056301521200
2056301522032 2056301521200
- 内外均为可变
a, b = [1], [2]
print(id(a), id(b))
x = [a, b]
print(id(x[0]), id(x[1]))
2056301345408 2056301503936
2056301345408 2056301503936
4. 拷贝
浅拷贝
- 数据深度为1,且数据类型为不可变数据类型,例如:元组、字符串、数字等
- id不变
import copy
x=1
y=copy.copy(x)
id(x),id(y)
(2056219879728, 2056219879728)
- 数据深度为1,且数据类型为可变数据类型,例如:列表、字典等
- id改变
import copy
x=[1,2]
y=copy.copy(x)
id(x),id(y)
(2056300472384, 2056301578432)
- 数据深度大于1,且数据类型:外层为不可变数据类型,内层也为不可变数据类型
- 外层id不变,内层id也不变
import copy
a, b = 'hjd', 'zyy'
x = (a, b)
print(id(x), id(x[0]), id(x[1]))
y = copy.copy(x)
print(id(y), id(y[0]), id(y[1]))
2056300284928 2056300470704 2056300472048
2056300284928 2056300470704 2056300472048
- 数据深度大于1,且数据类型:外层为不可变数据类型,内层为可变数据类型
- 外层id不变,但是内层id也不变
import copy
a, b = [1],[2]
x = (a, b)
print(id(x), id(x[0]), id(x[1]))
y = copy.copy(x)
print(id(y), id(y[0]), id(y[1]))
2056300289280 2056300472384 2056301577280
2056300289280 2056300472384 2056301577280
- 数据深度大于1,且数据类型:外层为可变数据类型,内层为不可变数据类型
- 外层id变,但是内层id不变
import copy
a, b = 'hjd', 'zyy'
x = [a, b]
print(id(x), id(x[0]), id(x[1]))
y = copy.copy(x)
print(id(y), id(y[0]), id(y[1]))
2056301251904 2056301517616 2056301515440
2056301576384 2056301517616 2056301515440
- 数据深度大于1,且数据类型:外层为可变数据类型,内层为可变数据类型
- 外层id变,但是内层id不变
import copy
a, b = [1], [2]
x = [a, b]
print(id(x), id(x[0]), id(x[1]))
y = copy.copy(x)
print(id(y), id(y[0]), id(y[1]))
2056300470784 2056301577280 2056301579136
2056301221888 2056301577280 2056301579136
深拷贝
- 数据深度为1,且数据类型为不可变数据类型,例如:元组、字符串、数字等
- id不变
import copy
x=1
y=copy.deepcopy(x)
id(x),id(y)
(2056219879728, 2056219879728)
- 数据深度为1,且数据类型为可变数据类型,例如:列表、字典等
- id改变
import copy
x=[1,2]
y=copy.deepcopy(x)
id(x),id(y)
(2056301250816, 2056301538304)
- 数据深度大于1,且数据类型:外层为不可变数据类型,内层也为不可变数据类型
- 外层id不变,内层id也不变
import copy
a, b = 'hjd', 'zyy'
x = (a, b)
print(id(x), id(x[0]), id(x[1]))
y = copy.deepcopy(x)
print(id(y), id(y[0]), id(y[1]))
2056300282432 2056301518384 2056301515440
2056300282432 2056301518384 2056301515440
- 数据深度大于1,且数据类型:外层为不可变数据类型,内层为可变数据类型
- 外层id改变,内层id也变
import copy
a, b = [1],[2]
x = (a, b)
print(id(x), id(x[0]), id(x[1]))
y = copy.deepcopy(x)
print(id(y), id(y[0]), id(y[1]))
2056301592448 2056301576384 2056301250816
2056300283840 2056300465216 2056301345408
- 数据深度大于1,且数据类型:外层为可变数据类型,内层为不可变数据类型
- 外层id变,但是内层id不变
import copy
a, b = 'hjd', 'zyy'
x = [a, b]
print(id(x), id(x[0]), id(x[1]))
y = copy.deepcopy(x)
print(id(y), id(y[0]), id(y[1]))
2056301578368 2056301249392 2056301307504
2056301250816 2056301249392 2056301307504
- 数据深度大于1,且数据类型:外层为可变数据类型,内层为可变数据类型
- 外层id变,内层id也变
import copy
a, b = [1], [2]
x = [a, b]
print(id(x), id(x[0]), id(x[1]))
y = copy.deepcopy(x)
print(id(y), id(y[0]), id(y[1]))
2056301576384 2056301345408 2056301583616
2056300472128 2056301578368 2056301579968
总结如下
外层是否可变 | 内层是否可变 | 是深拷贝 | 是浅拷贝 | 外层id改变 | 内层id改变 |
---|---|---|---|---|---|
无 | × | × | √ | 无 | × |
无 | √ | × | √ | 无 | √ |
× | × | × | √ | × | × |
× | √ | × | √ | × | × |
√ | × | × | √ | √ | × |
√ | √ | × | √ | √ | × |
无 | × | √ | × | 无 | × |
无 | √ | √ | × | 无 | √ |
× | × | √ | × | × | × |
× | √ | √ | × | √ | √ |
√ | × | √ | × | √ | × |
√ | √ | √ | × | √ | √ |