python - 为什么元组可以包含可变项?

如果元组是不可变的,那么为什么它可以包含可变项?

当一个可变项(如列表)被修改时,它所属的元组保持不变,这似乎是一个矛盾。

最佳答案

这是一个很好的问题。

关键的见解是元组无法知道其中的对象是否可变。使对象可变的唯一方法是拥有一个更改其数据的方法。一般来说,没有办法检测到这一点。

另一个见解是 Python 的容器实际上并不包含任何东西。相反,它们保留对其他对象的引用。同样,Python 的变量与编译语言中的变量不同。相反,变量名称只是 namespace 字典中的键,它们与相应的对象相关联。 Ned Batchhelder 在他的 blog post 中很好地解释了这一点。 .无论哪种方式,对象只知道它们的引用计数;他们不知道这些引用是什么(变量、容器或 Python 内部)。

这两个见解共同解释了您的谜团(为什么“包含”列表的不可变元组似乎会在基础列表发生变化时发生变化)。事实上,元组并没有改变(它对其他对象的引用仍然与之前相同)。元组不能改变(因为它没有变异方法)。当列表发生变化时,元组没有收到变化通知(列表不知道它是被变量、元组还是另一个列表引用)。

当我们谈到这个话题时,这里有一些其他想法可以帮助您完成关于元组是什么、它们如何工作以及它们的预期用途的心理模型:

  1. 元组的特征较少在于它们的不变性,而更多地在于它们的预期目的。
    元组是 Python 在一个屋檐下收集异构信息的一种方式。例如, s = ('www.python.org', 80) 将字符串和数字组合在一起,以便主机/端口对可以作为套接字(复合对象)传递。从这个角度来看,拥有可变组件是完全合理的。

  2. 不变性与另一个属性密切相关,hashability .但是哈希性并不是一个绝对的属性。如果元组的组件之一不可散列,则整个元组也不可散列。例如,t = ('red', [10, 20, 30]) 不可散列。

最后一个示例显示了一个包含字符串和列表的 2 元组。元组本身不是可变的(即它没有任何方法可以更改其内容)。同样,字符串是不可变的,因为字符串没有任何变异方法。列表对象确实具有变异方法,因此可以更改。这表明可变性是对象类型的一个属性——有些对象具有可变方法,有些则没有。这不会因为对象嵌套而改变。

记住两件事。首先,不变性不是魔术——它只是缺少变异方法。其次,对象不知道哪些变量或容器引用了它们——它们只知道引用计数。

希望这对你有用:-)

https://stackoverflow.com/questions/9755990/

相关文章:

python - Python 是否优化尾递归?

python - 只读取文件的第一行?

mysql - 如何测试MySQL在哪个端口上运行以及是否可以连接?

python - 迭代模板中的模型实例字段名称和值

python - 获取列表的内容并将其附加到另一个列表

linux - 我什么时候应该在 shell 变量周围加上引号?

linux - 如何重定向已运行进程的输出

c - Linux中的itoa函数在哪里?

regex - 如何使用 wget 下载整个目录和子目录?

linux - 移动除一个以外的所有文件