2021-09-13 05:23:27
在Python中,对象根据其值是否可以被修改分为可变类型和不可变类型。理解这一区别对编写高效、无副作用的代码至关重要。以下是详细解析:
一、可变类型(Mutable Types)可变类型的对象在创建后可以直接修改其内容,而无需创建新对象。常见可变类型包括:
列表(List)
通过索引直接修改元素:
my_list = [1, 2, 3]my_list[0] = 10 # 修改为 [10, 2, 3]通过方法修改(如 append()、remove()):
my_list.append(4) # 变为 [10, 2, 3, 4]通过 del 删除元素:
del my_list[1] # 变为 [10, 3, 4]字典(Dictionary)
通过键直接修改值或添加新键值对:
my_dict = {"a": 1}my_dict["a"] = 10 # 修改值my_dict["b"] = 2 # 添加新键值对集合(Set)
通过方法(如 add()、remove())动态修改:
my_set = {1, 2}my_set.add(3) # 变为 {1, 2, 3}自定义类对象
类的属性可在实例化后修改:
class MyClass: def __init__(self, value): self.value = valueobj = MyClass(10)obj.value = 20 # 直接修改属性特点:
不可变类型的对象一旦创建,其值不能被修改。任何修改操作都会生成新对象。常见不可变类型包括:
字符串(String)
无法通过索引直接修改:
s = "hello"s[0] = "H" # 报错:TypeError方法调用返回新字符串:
new_s = s.replace("h", "H") # 原字符串不变,new_s 为 "Hello"元组(Tuple)
元组本身不可变,但若包含可变对象(如列表),可变对象的内容可修改:
t = (1, [2, 3])t[1][0] = 99 # 合法,修改了元组中的列表数字类型(int, float, complex)
数学运算会生成新对象:
x = 10x += 1 # 创建新对象,x 指向 11不可变集合(frozenset)
类似集合,但创建后不能修改:
fs = frozenset([1, 2])fs.add(3) # 报错:AttributeError特点:
赋值行为
对不可变类型重新赋值会创建新对象,原对象不变:
a = 10b = aa = 20 # b 仍为 10可变类型的赋值是引用传递,修改会影响所有引用:
list1 = [1, 2]list2 = list1list1.append(3) # list2 也变为 [1, 2, 3]哈希性
不可变类型(如字符串、元组)可哈希,可用作字典键;可变类型(如列表)不可哈希。
性能权衡
不可变类型在多线程环境中更安全,但频繁修改时性能较差。
可变类型适合需要动态更新的场景(如数据收集)。
理解这两类对象的特性,能帮助你避免常见陷阱(如意外修改共享数据),并写出更健壮的Python代码。