Python中不可变的对象_python可变对象与不可变对象
在 Python 中,对象分为可变对象与不可变对象,二者在进行操作时有着截然不同的表现,下面我们通过具体示例来深入理解一下。
可变对象示例(以列表 list 为例)
对于像列表(list)这样的可变对象,当对其进行相关操作时,列表内部的内容是能够发生改变的。例如:
a = ['c', 'b', 'a']
a.sort()
print(a)
['a', 'b', 'c']
在上述代码中,首先创建了一个包含字符元素的列表 a,其初始值为 ['c', 'b', 'a']。接着,调用了列表的 sort 方法对列表进行排序操作,执行完 sort 方法后,可以看到列表 a 的内容变为了 ['a', 'b', 'c']。这充分体现了可变对象的特性,即可以直接在原对象上对其内部元素进行修改,改变其自身的状态。
不可变对象示例(以字符串 str 为例)
然而,对于像字符串(str)这样的不可变对象,情况就大不一样了。我们来看下面的代码:
a = 'abc'
a.replace('a', 'A')
print(a)
abc
在这段代码中,先是定义了一个字符串 a,其值为 'abc'。随后调用了字符串的 replace 方法,试图将其中的字符 'a' 替换为 'A',此时确实能看到 replace 方法返回了一个新的字符串 'Abc',但当我们再次查看变量 a 的值时,会发现它仍然是 'abc',并没有发生改变。这可能会让一些人感到疑惑,那应该如何去理解这种现象呢?
我们不妨把代码稍作修改,如下所示:
a = 'abc'
b = a.replace('a', 'A')
print(b)
print(a)
Abc
abc
在这个修改后的代码示例中,关键要明确的一点是,a 是一个变量,而 'abc' 才是真正的字符串对象。在日常表述中,我们有时会说 “对象 a 的内容是 'abc'”,但准确来讲,其实是指变量 a 指向了一个内容为 'abc' 的字符串对象,用图形化的方式来表示大概如下:
┌───┐ ┌───────┐
│ a │────?│ 'abc' │
└───┘ └───────┘
当我们调用 a.replace('a', 'A') 时,实际上是在字符串对象 'abc' 上调用了 replace 方法。这里要注意的是,虽然这个方法名为 replace,但它并不会改变原字符串 'abc' 的内容。恰恰相反,replace 方法的执行逻辑是基于原字符串创建了一个新的字符串 'Abc',并将这个新字符串作为返回值返回。
当我们接着使用变量 b 去接收这个返回的新字符串时,就更容易理解整个过程了。此时的情况可以用下面的图形来表示:
┌───┐ ┌───────┐
│ a │────?│ 'abc' │
└───┘ └───────┘
┌───┐ ┌───────┐
│ b │────?│ 'Abc' │
└───┘ └───────┘
也就是说,变量 a 依旧指向原来那个内容为 'abc' 的字符串对象,而变量 b 则指向了通过 replace 方法新创建出来的内容为 'Abc' 的字符串对象。
综上所述,对于不可变对象而言,无论调用对象自身的哪一个方法,都不会改变该对象自身原本的内容。这些方法的实现机制往往是创建新的对象,并将新对象作为返回值返回,通过这样的方式,就从根本上保证了不可变对象始终维持其不可变的特性。这也是不可变对象与可变对象在行为表现上的一个重要区别,理解这一点对于正确把握 Python 中不同类型对象的使用以及代码逻辑的清晰性都有着重要意义。