本文介绍了为什么元组可以包含可变项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If a tuple is immutable then why can it contain mutable items?

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

It is seemingly a contradiction that when a mutable item such as a list does get modified, the tuple it belongs to maintains being immutable.

推荐答案

这是一个很好的问题.

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

The key insight is that tuples have no way of knowing whether the objects inside them are mutable. The only thing that makes an object mutable is to have a method that alters its data. In general, there is no way to detect this.

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

Another insight is that Python's containers don't actually contain anything. Instead, they keep references to other objects. Likewise, Python's variables aren't like variables in compiled languages; instead the variable names are just keys in a namespace dictionary where they are associated with a corresponding object. Ned Batchhelder explains this nicely in his blog post. Either way, objects only know their reference count; they don't know what those references are (variables, containers, or the Python internals).

一起,这两个见解解释了您的奥秘(为什么当基础列表更改时,包含"列表的不可变元组似乎也会更改).事实上,元组并没有改变(它仍然具有与之前相同的对其他对象的引用).元组不能改变(因为它没有变异方法).当列表更改时,元组没有收到更改通知(列表不知道它是否被变量、元组或另一个列表引用).

Together, these two insights explain your mystery (why an immutable tuple "containing" a list seems to change when the underlying list changes). In fact, the tuple did not change (it still has the same references to other objects that it did before). The tuple could not change (because it did not have mutating methods). When the list changed, the tuple didn't get notified of the change (the list doesn't know whether it is referred to by a variable, a tuple, or another list).

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

While we're on the topic, here are a few other thoughts to help complete your mental model of what tuples are, how they work, and their intended use:

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

  1. Tuples are characterized less by their immutability and more by their intended purpose.
    Tuples are Python's way of collecting heterogeneous pieces of information under one roof. For example,s = ('www.python.org', 80)brings together a string and a number so that the host/port pair can be passed around as a socket, a composite object. Viewed in that light, it is perfectly reasonable to have mutable components.

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

Immutability goes hand-in-hand with another property, hashability. But hashability isn't an absolute property. If one of the tuple's components isn't hashable, then the overall tuple isn't hashable either. For example, t = ('red', [10, 20, 30]) isn't hashable.

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

The last example shows a 2-tuple that contains a string and a list. The tuple itself isn't mutable (i.e. it doesn't have any methods that for changing its contents). Likewise, the string is immutable because strings don't have any mutating methods. The list object does have mutating methods, so it can be changed. This shows that mutability is a property of an object type -- some objects have mutating methods and some don't. This doesn't change just because the objects are nested.

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

Remember two things. First, immutability is not magic -- it is merely the absence of mutating methods. Second, objects don't know what variables or containers refer to them -- they only know the reference count.

希望,这对你有用:-)

Hope, this was useful to you :-)

这篇关于为什么元组可以包含可变项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 08:06