自学Python:第九篇可变类型与不可变类型

自学Python:第九篇可变类型与不可变类型
最新回答
花颜诱人醉

2021-09-13 05:23:27

在Python中,对象根据其值是否可以被修改分为可变类型不可变类型。理解这一区别对编写高效、无副作用的代码至关重要。以下是详细解析:

一、可变类型(Mutable Types)

可变类型的对象在创建后可以直接修改其内容,而无需创建新对象。常见可变类型包括:

  1. 列表(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]
  2. 字典(Dictionary)

    通过键直接修改值或添加新键值对:

    my_dict = {"a": 1}my_dict["a"] = 10 # 修改值my_dict["b"] = 2 # 添加新键值对
  3. 集合(Set)

    通过方法(如 add()、remove())动态修改:

    my_set = {1, 2}my_set.add(3) # 变为 {1, 2, 3}
  4. 自定义类对象

    类的属性可在实例化后修改:

    class MyClass: def __init__(self, value): self.value = valueobj = MyClass(10)obj.value = 20 # 直接修改属性

特点

  • 内存效率高:修改操作直接作用于原对象,避免频繁创建新对象。
  • 潜在副作用:多个变量引用同一可变对象时,修改会影响所有引用。
二、不可变类型(Immutable Types)

不可变类型的对象一旦创建,其值不能被修改。任何修改操作都会生成新对象。常见不可变类型包括:

  1. 字符串(String)

    无法通过索引直接修改:

    s = "hello"s[0] = "H" # 报错:TypeError

    方法调用返回新字符串:

    new_s = s.replace("h", "H") # 原字符串不变,new_s 为 "Hello"
  2. 元组(Tuple)

    元组本身不可变,但若包含可变对象(如列表),可变对象的内容可修改:

    t = (1, [2, 3])t[1][0] = 99 # 合法,修改了元组中的列表
  3. 数字类型(int, float, complex)

    数学运算会生成新对象:

    x = 10x += 1 # 创建新对象,x 指向 11
  4. 不可变集合(frozenset)

    类似集合,但创建后不能修改:

    fs = frozenset([1, 2])fs.add(3) # 报错:AttributeError

特点

  • 安全性高:避免意外修改,适合作为字典的键或集合的元素。
  • 内存开销:频繁修改会生成多个临时对象,可能影响性能。
三、关键区别与注意事项
  1. 赋值行为

    对不可变类型重新赋值会创建新对象,原对象不变:

    a = 10b = aa = 20 # b 仍为 10

    可变类型的赋值是引用传递,修改会影响所有引用:

    list1 = [1, 2]list2 = list1list1.append(3) # list2 也变为 [1, 2, 3]
  2. 哈希性

    不可变类型(如字符串、元组)可哈希,可用作字典键;可变类型(如列表)不可哈希。

  3. 性能权衡

    不可变类型在多线程环境中更安全,但频繁修改时性能较差。

    可变类型适合需要动态更新的场景(如数据收集)。

四、总结
  • 可变类型:列表、字典、集合、自定义对象。支持原地修改,高效但需注意引用副作用。
  • 不可变类型:数字、字符串、元组、不可变集合。值不可变,适合需要稳定性的场景。

理解这两类对象的特性,能帮助你避免常见陷阱(如意外修改共享数据),并写出更健壮的Python代码。