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

发布于 2021-02-02 23:09:03

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

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

关注者
0
被浏览
57
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    这是一个很好的问题。

    关键的见解是,元组无法知道其中的对象是否可变。使对象可变的唯一方法是拥有一种更改其数据的方法。通常,无法检测到此情况。

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

    这两种见解共同解释了你的奥秘(为什么当基础列表更改时,包含列表的不可变元组似乎也会更改)。实际上,元组没有变化(它对其他对象的引用与以前相同)。元组无法更改(因为它没有变异方法)。当列表更改时,没有通知元组更改(列表不知道它是由变量,元组还是其他列表引用)。

    当我们讨论该主题时,还有一些其他想法可以帮助你完善关于元组是什么,它们如何工作以及其预期用途的思维模型:

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

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

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

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



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看