描述 | 备注 | |
---|---|---|
is | 对象的内存比较 | id(x) |
== | 对象的值比较 | |
浅拷贝 | copy.copy()拷贝原对象中子对象的引用 | 原对象的子对象是可变,改变后会影响原对象 |
深拷贝 | copy.deepcopy()拷贝原对象中的每个子对象 | 深拷贝后对象和原对象互不影响 |
可变对象 | list,dict,set | 当其改变时,所有指向这个对象的变量都会改变 |
不可变对象 | str,int,tuple | 简单的赋值只能改变其中一个变量的值,其余变量则不受影响 |
函数参数 | 变量引用的传递 |
==和is的区别
- ==
比较对象是:对象的值 - is
比较对象是:对象的内存地址 - id(x)
获得对象的内存地址
比较操作符'=='表示比较对象间的值是否相等,而'is'表示比较对象的标识是否相等,即它们是否指向同一个内存地址。比较操作符'is'效率优于'==',因为'is'操作符无法被重载,执行'is'操作只是简单的获取对象的 ID,并进行比较;而'=='操作符则会递归地遍历对象的所有值,并逐一比较。
浅拷贝和深拷贝
- 浅拷贝copy.copy()
浅拷贝,是指从新申请一快内存,创建一个新的对象,里面的元素是原对象的子对象的应用。原对象的子对象不可变(元祖),与深拷贝无差异;若子对象可变,浅拷贝会有负作用
实例
l1 = [[1, 2], (30, 40)]
l2 = list(l1)
print(l1)
# [[1, 2], (30, 40)]
print(l2)
# [[1, 2], (30, 40)]
l1.append('100')
print(l1)
# [[1, 2], (30, 40), '100']
print(l2)
# [[1, 2], (30, 40)]
l1[0].append(3)
print(l1)
# [[1, 2, 3], (30, 40), '100']
print(l2)
# [[1, 2, 3], (30, 40)]
l1[1] += (50,)
print(l1)
# [[1, 2, 3], (30, 40, 50), '100']
print(l2)
# [[1, 2, 3], (30, 40)]
- 深拷贝copy.deepcopy()
深度拷贝指的是重新申请一块内存,创建一个新的对象,并且将原对象中的对象以递归的方式,通过创建新的子对象拷贝到新对象中。
实例
import copy
l1 = [[1, 2], (30, 40)]
l2 = copy.deepcopy(l1)
l1.append(100)
l1[0].append(3)
l1
[[1, 2, 3], (30, 40), 100]
l2
[[1, 2], (30, 40)]
变量赋值
- 变量赋值:变量指向对象,并不表示拷贝对象给变量;一个对象可以被多个变量所指向
- 可变对象(list,dict,set)的改变,会影响所有指向该对象的变量
- 不可变对象(str,int,tuple),所指向该对象的变量的值总是不一样,也不会改变。但通过+=更新不可变对象的值时,会返回一个新的对象
- 变量可被输出;对象无法被输出,当引用计数为0后,会被系统回收
参数传递
python中函数的参数传递为对象的引用传递
- 不可变对象的函数参数
def my_func2(b):
b = 2
a = 1
my_func2(a)
#输出
a=1
-可变对象的函数参数
def my_func3(l2):
l2.append(4)
l1 = [1, 2, 3]
my_func3(l1)
l1
[1, 2, 3, 4]
def my_func4(l2):
l2 = l2 + [4]
l1 = [1, 2, 3]
my_func4(l1)
l1
[1, 2, 3]
l2.append(4),修改对象
l2 = l2 + [4], 新建对象[1, 2, 3, 4],并赋值给l2