原文地址是哪真的忘了
赋值就是我们通过=把一个变量的值赋给另一变量,相当于引用,这里的赋值又可以分为几类
str_a = str_b = 'hello' # 相当于 str_a = 'hello' 和 str_b = str_a 这两条语句
str_c = 'hello'
print(str_b is str_a) # 输出: True
print(str_c is str_a) # 输出:True,这里输出True就是因为缓存机制,str_c和str_a的值相等,都是'hello',且长度在20以内
# 整型赋值
int_a = int_b = 100 #
int_c = 10 * 10
print(int_b is int_a) # 输出True
print(int_c is int_a) # 输出True
str_a = str_b = 'a' * 4097 # 相当于 str_a = 'a' * 4097 和 str_b = str_a 这两条语句
str_c = 'a' * 4097
print(str_b is str_a) # 输出: True
print(str_c is str_a) # 输出:False,这里输出False是因为虽然str_c和str_a的值相等,但长度在为4097,超过了缓存最大长度4096
# 整型赋值
int_a = int_b = 1000 # 相当于 int_a = 100 和 int_b = int_a 这两条语句
int_c = 10 * 10 * 10
print(int_b is int_a) # 输出True
print(int_c is int_a) # 输出False
list_a = list_b = [1, 2, 3] # 相当于 list_a = [1, 2, 3] 和 list_b = list_a 这两条语句
list_c = [1, 2, 3]
print(list_b is list_a) # 输出True,修改list_a会影响list_b,反之亦然
print(list_c is list_a) # 输出False
— 切片就是从某个对象中抽取部分的操作,切片操作得到的对象和原对象是不同的对象,但其子元素有可能是同一对象,这里分为几种情况说明,切片相当于浅拷贝。
list_a = [1, 2, 3, 4]
list_b = list_a[:] # 完全切片
print(list_b is list_a) # 输出False,list_a和list_b是不同的对象
list_a.append(5) # 对对象list_a进行追加元素操作
# list_a[0] = 11 # 对对象list_a进行修改子元素操作
# del list_a[-1] # 对对象list_a进行删除子元素操作
print(list_a) # 输出[1, 2, 3, 4, 5]
print(list_b) # 输出[1, 2, 3, 4]
print(list_a is list_b) # 输出False,不是同一个对象
list_a = [1, 2, [3], 4] # 和上面不同在于list_a[2]是一个可变对象
list_b = list_a[:] # 完全切片
print(list_b is list_a) # 输出False,list_a和list_b是不同的对象
list_a[2].append(44) # 对可变子元素进行追加子元素操作,注意是对子元素本身进行追加操作
# list_a[2][0] = 33 # 对可变子元素进行修改子元素操作,注意是对子元素本身的子元素进行修改操作,而不是修改list_a的子元素
# del list_a[2][-1] # 对可变子元素进行删除子元素操作,注意是对子元素本身的子元素进行删除操作,而不是删除list_a的子元素
print(list_) # 输出[1, 2, [3, 44], 4]
print(list_b) # 输出[1, 2, [3, 44], 4]
print(list_b is list_a) # 输出False,list_a和list_b是不同的对象
print(list_a[2] is list_b[2]) # 输出True,在切片操作中,可变子元素是相当于赋值操作的,即list_a[2]和list_b[2]是同一个对象
# 说明:这种情况是不区分完全切片和不完全切片的,只要切片得到的子元素是可变对象的,都满足这种情况,以下代码就是不完全切片的例子,和完全切片的情况一样的
list_c = list_a[:3] # 不完全切片,但切片得到的list_c[2]是一个可变对象
print(list_c is list_a) # 输出False,list_a和list_c是不同的对象
list_a[2][0] = 33 # 修改可变子元素的子元素,注意是修改子元素本身的子元素,而不是修改list_a的子元素
print(list_a) # 输出[1, 2, [33, 44], 4]
print(list_c) # 输出[1, 2, [33, 44], 4]
print(list_c is list_a) # 输出False,list_a和list_c是不同的对象
print(list_a[2] is list_c[2]) # 输出True,在切片操作中,可变子元素是相当于赋值操作的,即list_a[2]和list_c[2]是同一个对象
import copy
a = 'hello'
b = copy.copy(a)
print(b is a) # 输出True,和赋值一样
c = 'a' * 4097
d = copy.copy(c)
print(d is c)
import copy
a = [1, [2, [3, [4]]]]
b = copy.copy(a)
print(b is a) # 输出False,浅拷贝可变对象得到的对象和原对象是不同的对象
print(b[0] is a[0]) # True,浅拷贝可变对象得到的对象的不可变子元素是同一对象,这和深拷贝是一样的
print(b[1] is a[1]) # True,浅拷贝可变对象得到的对象的可变子元素也是同一对象,这和深拷贝是不一样的
# 下面两个和上面两个是一样的情况,一一对应,只不过层级更深而已
print(b[1][0] is a[1][0]) # True
print(b[1][1] is a[1][1]) # True
b[0] = 111 # 对b[0]直接修改
b.append(3434) # 对b进行追加操作
print(a, b) # 这里a和b不一样了
b[1][0] = 22 # 对子元素b[1][0]直接修改
b[1].append(5) # 对子元素b[1]进行追加操作
print(b[1], a[1]) # 这里的b[1]和a[1]还是保持一样的
不可变对象的深拷贝
import copy
a = 'a' * 10000
b = copy.deepcopy(a)
print(b is a) #
输出True,深拷贝不可变对象得到的对象和原对象是同一对象 —
变对象的深拷贝
import copy
c = [1, [2, [3, [4]]]]
d = copy.deepcopy(c)
print(d is c) # 输出False,深拷贝可变对象得到的对象和原对象是不同的对象
print(d[0] is c[0]) # 输出True,深拷贝可变对象得到的对象的不可变子元素是同一对象
print(d[1] is c[1]) #
输出False,深拷贝可变对象得到的对象的可变子元素是不同的对象
# 下面两个和上面两个是一样的情况,一一对应,只不过层级更深而已
print(d[1][0] is c[1][0]) # 输出True
print(d[1][1] is c[1][1]) # 输出False