Python中可变和不可变对象的深入讲解

  • Post category:Python

Python中可变和不可变对象的深入讲解

在 Python 中,对象可以被分为可变对象和不可变对象两种类型。这个概念很重要,因为在编写应用程序时,你需要明确是否可以在原地修改对象。本文将深入讲解这个概念,探讨可变和不可变对象的区别,以及如何在 Python 中正确使用它们。

可变对象和不可变对象的区别

可变对象和不可变对象的最大区别在于,可变对象可以在原地修改,而不可变对象则不能。例如,你可以在原地更改列表(list)的元素,但是不能在原地更改字符串(str)的某一个字符。

Python 中的数据类型可以分为两类:可变和不可变。可变对象在其生命周期中可以被修改,而不可变对象在创建之后则不能再被修改,只能使用新的对象替换原有对象。常见的可变对象包括列表、字典和集合,而常见的不可变对象包括整数、浮点数、布尔值、字符串和元组等。

我们来看一下一个简单的例子,说明可变对象和不可变对象的区别:

my_list = [1, 2, 3]
id_before = id(my_list)  # 获取my_list在内存中的地址
my_list.append(4)
id_after = id(my_list)  # 获取my_list在内存中的新地址
print(id_before == id_after)  # True,说明my_list在原地被修改了

上述代码中,我们首先创建了一个包含3个整数的列表 my_list,然后获取了其在内存中的地址 id_before。接着,我们调用了列表的 append 方法,在列表中添加了一个新的元素 4,再次获取了 my_list 在内存中的地址 id_after。最后,我们比较了 id_beforeid_after 的值,它们相等,说明 my_list 在原地被修改了。

我们再看一个示例,说明不可变对象不能在原地修改:

my_str = 'hello'
id_before = id(my_str)  # 获取my_str在内存中的地址
my_str += ' world'
id_after = id(my_str)  # 获取my_str在内存中的新地址
print(id_before == id_after)  # False,说明my_str不能在原地被修改

上述代码中,我们首先创建了一个字符串 my_str,它包含了单词 ‘hello’。接着,我们尝试使用 += 运算符来在其后面添加新的内容 ‘ world’,这个操作实际上是用一个新的字符串替换了原来的字符串,所以 my_str 已经是一个新的对象,它在内存中的地址为 id_after。最后,我们比较了 id_beforeid_after 的值,它们不相等,说明 my_str 不能在原地被修改。

可变对象和不可变对象的合理使用

在编写 Python 应用程序时,合理使用可变对象和不可变对象是非常重要的。对于不可变对象,使用 is 关键字或者 id() 函数来比较对象是否相等,对于可变对象,则可以直接使用 == 运算符比较对象是否相等。

下面我们再来看一个示例,说明如何合理使用可变和不可变对象:

my_dict = {'name': 'Lucy', 'age': 22}
id_before = id(my_dict)  # 获取my_dict在内存中的地址
my_dict['age'] = 23
id_after = id(my_dict)  # 获取my_dict在内存中的新地址
print(id_before == id_after)  # True,说明my_dict在原地被修改了

上述代码中,我们首先创建了一个包含两个键值对的字典 my_dict,然后获取了其在内存中的地址 id_before。接着,我们使用了字典的索引方式来修改 my_dict 中的 ‘age’ 键对应的值,再次获取了 my_dict 在内存中的地址 id_after。最后,我们比较了 id_beforeid_after 的值,它们相等,说明 my_dict 在原地被修改了。

可见,合理使用可变对象和不可变对象可以使你的程序更加高效,也能在一些特殊情况下避免各种问题。