如果一个元组是不可变的,那么为什么它可以包含可变项?
当一个可变项(如列表)被修改时,它所属的元组仍然是不可变的,这似乎是一个矛盾。
如果一个元组是不可变的,那么为什么它可以包含可变项?
当一个可变项(如列表)被修改时,它所属的元组仍然是不可变的,这似乎是一个矛盾。
当前回答
首先,“不可变”这个词对不同的人有不同的含义。我特别喜欢Eric Lippert在他的博客文章中对不变性的分类。在书中,他列举了以下几种不变性:
Realio-trulio不变性 写一次不变性 冰棒不变性 浅不变与深不变 不变的外观 观察不变性
这些元素可以以不同的方式组合在一起,从而创造出更多类型的不变性,而且我相信还有更多类型的不变性存在。您似乎对深层(也称为传递性)不可变感兴趣,在这种不可变对象中,不可变对象只能包含其他不可变对象。
这里的关键在于,深度不变性只是许许多多不变性中的一种。你可以采用你喜欢的任何一种,只要你意识到你的“不可变”概念可能与别人的“不可变”概念不同。
其他回答
元组是不可变的,因为元组本身不能扩展或收缩,而不是所有包含自身的项都是不可变的。否则元组是无趣的。
我在这里大胆地说一下,这里的相关部分是,虽然你可以改变一个列表的内容,或者一个对象的状态,包含在一个元组中,但你不能改变的是对象或列表在那里。如果你有一些东西依赖于[3]是一个列表,即使是空的,那么我可以看到这是有用的。
不能更改其项的id。所以它总是包含相同的项。
$ python
>>> t = (1, [2, 3])
>>> id(t[1])
12371368
>>> t[1].append(4)
>>> id(t[1])
12371368
这是因为元组不包含列表、字符串或数字。它们包含对其他对象的引用不能改变元组包含的引用序列并不意味着你不能改变与这些引用相关的对象
1. 对象、值和类型(见:倒数第二段) 2. 标准类型层次结构(参见:“不可变序列”)
一个原因是,在Python中没有将可变类型转换为不可变类型的通用方法(请参阅被拒绝的PEP 351,以及关于它为什么被拒绝的链接讨论)。因此,如果有这个限制,就不可能在元组中放入各种类型的对象,包括几乎任何用户创建的不可哈希对象。
字典和集合有这个限制的唯一原因是它们要求对象是可哈希的,因为它们在内部实现为哈希表。但是要注意,具有讽刺意味的是,字典和集合本身并不是不可变的(或可哈希的)。元组不使用对象的哈希,因此它的可变性无关紧要。