1.可变对象和不可变对象
1.1 不可变对象和可变对象的定义
- 不可变对象: 可以理解为在对象创建后(创建并分配了 ID(内存地址))的情况下,其内容无法修改。任何尝试修改其内容的操作都会创建一个新的对象。
- 可变对象: 在对象创建后,在不改变 ID 的情况下,其内容是可以修改的
1.2 常见的可变对象和不可变对象及其示例
1.2.1 可变对象
- 常见可变对象
- 列表(list)
- 字典(dict)
- 集合(set)
- 自定义对象
- 可变对象修改示例
- 示例代码
# 列表是可变的 print("######### 列表测试 #########") my_list = [1, 2, 3] print(" 列表修改前的内容 == ", my_list) # 输出: [1, 2, 3] print(" 列表修改前的id == ", id(my_list)) my_list[0] = 10 # 修改第一个元素 print(" 列表修改后的内容 == ", my_list) # 输出: [10, 2, 3] print(" 列表修改后的id == ", id(my_list))# 字典是可变的 print("######### 字典测试 #########") my_dict = {'a': 1, 'b': 2} print(" 字典修改前的内容 == ", my_dict) # 输出: {'a': 1, 'b': 2} print(" 字典修改前的id == ", id(my_dict)) my_dict['a'] = 10 # 修改键'a'的值 print(" 字典修改后的内容 == ", my_dict) # 输出: {'a': 10, 'b': 2} print(" 字典修改后的id == ", id(my_dict))
- 运行输出
######### 列表测试 #########列表修改前的内容 == [1, 2, 3]列表修改前的id == 2529155928448列表修改后的内容 == [10, 2, 3]列表修改后的id == 2529155928448 ######### 字典测试 #########字典修改前的内容 == {'a': 1, 'b': 2}字典修改前的id == 2529156249664字典修改后的内容 == {'a': 10, 'b': 2}字典修改后的id == 2529156249664
- 示例代码
1.2.2 不可变对象
- 常见不可变对象
- 整数(int)
- 浮点数(float)
- 字符串(str)
- 元组(tuple)
- 不可变对象修改示例
- 示例代码
# 整数是不可变的 print("######### 整数测试 #########") x = 5 print(" 整数修改前的内容 == ", x) print(" 整数修改前的id == ", id(x)) x = 10 # 这里实际上是创建了一个新的整数对象,而不是修改原来的整数对象 print(" 整数修改后的内容 == ", x) print(" 整数修改后的id == ", id(x))# 字符串是不可变的 print("######### 字符串测试 #########") my_str = "hello" print(" 字符串修改前的内容 == ", my_str) print(" 字符串修改前的id == ", id(my_str)) my_str = "world" # 这里也是创建了一个新的字符串对象,而不是修改原来的字符串 print(" 字符串修改后的内容 == ", my_str) print(" 字符串修改后的id == ", id(my_str))
- 运行输出
######### 整数测试 #########整数修改前的内容 == 5整数修改前的id == 140723914734136整数修改后的内容 == 10整数修改后的id == 140723914734296 ######### 字符串测试 #########字符串修改前的内容 == hello字符串修改前的id == 2174965650112字符串修改后的内容 == world字符串修改后的id == 2174965650400
- 示例代码
2. 浅拷贝(shallow copy)
2.1 浅拷贝定义
- 浅拷贝 :仅拷贝 目标对象 ,对于 目标对象 所包含的子对象仅进行 引用
- 仅拷贝 可变对象 ,因为 不可变对象 是不会改变的,所以对其进行拷贝是没有意义的,所以,对于 不可变对象 仅仅进行引用。
- 浅拷贝 仅拷贝 目标对象 ,所以只有目标对象是可变对象和目标对象是不可变对象两种情况。
2.2 浅拷贝方法
- 使用标准库的 copy模块 的 copy函数
import copy list1 = [1, 2, 3] list2 = copy.copy(list1)
- 使用数据类型本身的构造器
# 列表 list1 = [1, 2, 3] list2 = list(list1) # 字典 dict1 = {1: 'a', 2: 'b'} dict2 = dict(dict1) #集合 set1 = {1, 2, 3} set2 = set(set1)
- 使用切片操作符 - 适用于列表
list1 = [1, 2, 3] list2 = list1[:]
- 使用对象自带的copy方法
dict1 = {1: [1, 2, 3], 2: 'b'} dict2 = dict1.copy()
2.3 浅拷贝可变对象的示例
- 示例代码
import copy print("########### original_list ###########") original_list = [("tuple_0", "tuple_1"), ["list_0", "list_1"], 3] print(" id(original_list) = ", id(original_list)) print(" id(original_list[0]) = ", id(original_list[0])) print(" id(original_list[1]) = ", id(original_list[1])) print(" id(original_list[2)) = ", id(original_list[2])) print("########### shallow_copied_list ###########") shallow_copied_list = copy.copy(original_list) print(" id(shallow_copied_list) = ", id(shallow_copied_list)) print(" id(shallow_copied_list[0]) = ", id(shallow_copied_list[0])) print(" id(shallow_copied_list[1]) = ", id(shallow_copied_list[1])) print(" id(shallow_copied_list[2)) = ", id(shallow_copied_list[2]))
- 代码输出
########### original_list ###########id(original_list) = 2593492160896id(original_list[0]) = 2593494296576id(original_list[1]) = 2593492162752id(original_list[2)) = 140723918731768 ########### shallow_copied_list ###########id(shallow_copied_list) = 2593494397824id(shallow_copied_list[0]) = 2593494296576id(shallow_copied_list[1]) = 2593492162752id(shallow_copied_list[2)) = 140723918731768
2.4 浅拷贝不可变对象的示例
- 代码示例
import copy print("########### original_tuple ###########") original_tuple = (("tuple_0", "tuple_1"), ["list_0", "list_1"], 3) print(" id(original_tuple) = ", id(original_tuple)) print(" id(original_tuple[0]) = ", id(original_tuple[0])) print(" id(original_tuple[1]) = ", id(original_tuple[1])) print(" id(original_tuple[2)) = ", id(original_tuple[2])) print("########### shallow_copied_tuple ###########") shallow_copied_tuple = copy.copy(original_tuple) print(" id(shallow_copied_tuple) = ", id(shallow_copied_tuple)) print(" id(shallow_copied_tuple[0]) = ", id(shallow_copied_tuple[0])) print(" id(shallow_copied_tuple[1]) = ", id(shallow_copied_tuple[1])) print(" id(shallow_copied_tuple[2)) = ", id(shallow_copied_tuple[2]))
- 代码输出
########### original_tuple ###########id(original_tuple) = 2327690951808id(original_tuple[0]) = 2327690438656id(original_tuple[1]) = 2327688304832id(original_tuple[2)) = 140723918731768 ########### shallow_copied_tuple ###########id(shallow_copied_tuple) = 2327690951808id(shallow_copied_tuple[0]) = 2327690438656id(shallow_copied_tuple[1]) = 2327688304832id(shallow_copied_tuple[2)) = 140723918731768
3. 深拷贝(deep copy)
3.1 深拷贝定义
- 深拷贝: 递归拷贝 目标对象 及 子对象 ,
- 仅拷贝 可变对象 ,因为 不可变对象 是不会改变的,所以对其进行拷贝是没有意义的,所以,对于 不可变对象 仅仅进行引用。
注:如果 不可变对象 中包含 可变对象 ,则也要对这个 父不可变对象 进行拷贝。
- 在递归拷贝过程中,只要 下级对象 中出现 可变对象, 则上级对象无论是 可变对象 还是 不可变对象 都要对其进行拷贝。对 下级 没有 可变对象 的不可变对象进行引用。
3.2 深拷贝方法
- 使用标准库的 copy模块 的 deepcopy 函数
import copy original_list = [1, 2, [3, 4]] deep_copied_list = copy.deepcopy(original_list)
3.3 深拷贝示例1
- 代码示例
import copy print("########### original_tuple ###########") original_tuple = (("tuple_0", "tuple_1", (1, 2)), ("list_0", "list_1", [12, 13]), 3) print(" id(original_tuple) = ", id(original_tuple)) print(" id(original_tuple[0]) = ", id(original_tuple[0])) print(" id(original_tuple[1]) = ", id(original_tuple[1])) print(" id(original_tuple[2)) = ", id(original_tuple[2])) print("########### shallow_copied_tuple ###########") shallow_copied_tuple = copy.deepcopy(original_tuple) print(" id(shallow_copied_tuple) = ", id(shallow_copied_tuple)) print(" id(shallow_copied_tuple[0]) = ", id(shallow_copied_tuple[0])) print(" id(shallow_copied_tuple[1]) = ", id(shallow_copied_tuple[1])) print(" id(shallow_copied_tuple[2)) = ", id(shallow_copied_tuple[2]))
- 代码输出
########### original_tuple ###########id(original_tuple) = 1933688192320id(original_tuple[0]) = 1933687798912id(original_tuple[1]) = 1933688291264id(original_tuple[2)) = 140723912702456 ########### shallow_copied_tuple ###########id(shallow_copied_tuple) = 1933688316480id(shallow_copied_tuple[0]) = 1933687798912id(shallow_copied_tuple[1]) = 1933688318400id(shallow_copied_tuple[2)) = 140723912702456
3.4 深拷贝示例2
-
代码示例
import copy print("########### original_tuple ###########") original_tuple = (("tuple_0", "tuple_1", (1, 2)), ("list_0", "list_1", (12, 13)), 3) print(" id(original_tuple) = ", id(original_tuple)) print(" id(original_tuple[0]) = ", id(original_tuple[0])) print(" id(original_tuple[1]) = ", id(original_tuple[1])) print(" id(original_tuple[2)) = ", id(original_tuple[2])) print("########### shallow_copied_tuple ###########") shallow_copied_tuple = copy.deepcopy(original_tuple) print(" id(shallow_copied_tuple) = ", id(shallow_copied_tuple)) print(" id(shallow_copied_tuple[0]) = ", id(shallow_copied_tuple[0])) print(" id(shallow_copied_tuple[1]) = ", id(shallow_copied_tuple[1])) print(" id(shallow_copied_tuple[2)) = ", id(shallow_copied_tuple[2]))
-
代码输出
########### original_tuple ###########id(original_tuple) = 1932263735232id(original_tuple[0]) = 1932263242880id(original_tuple[1]) = 1932263636288id(original_tuple[2)) = 140723912702456 ########### shallow_copied_tuple ###########id(shallow_copied_tuple) = 1932263735232id(shallow_copied_tuple[0]) = 1932263242880id(shallow_copied_tuple[1]) = 1932263636288id(shallow_copied_tuple[2)) = 140723912702456