关于immutability:为什么Python中的整数是不可变的?

Why are integers immutable in Python?

本问题已经有最佳答案,请猛点这里访问。

我了解Python中可变对象和不可变对象之间的区别。我读过许多讨论分歧的文章。但是,我没有读过任何关于整数为什么是不可变对象的内容。

有什么原因吗?或者答案是"就是这样"?

编辑:我被提示"区分"这个问题和其他问题,因为它似乎是以前问过的问题。然而,我相信我所问的更多是一个哲学上的python问题,而不是技术上的python问题。

似乎python中的"primitive"对象(即字符串、布尔值、数字等)是不可变的。我还注意到,由原语(如dict、list、classes)组成的派生数据类型是可变的。

绘制线条的位置是否为对象可变?原始与衍生?


使整数可变对于我们使用它们的方式是非常违反直觉的。

考虑这个代码片段:

1
2
a = 1       # assign 1 to a
b = a+2     # assign 3 to b, leave a at 1

在执行这些赋值之后,我们希望a的值为1,b的值为3。加法操作是从存储在整数中的整数和整数2的实例中创建一个新的整数值。如果加法运算只取了a处的整数并对其进行了变异,那么a和b的值都将为3。

因此,我们期望算术运算为它们的结果创建新的值,而不是改变它们的输入参数。

然而,在某些情况下,改变数据结构更加方便和高效。现在假设list.append(x)没有修改list,而是返回了一个新的list副本,并附加了x。这样的函数:

1
2
3
4
5
def foo():
  nums = []
  for x in range(0,10):
    nums.append(x)
  return nums

只会返回空列表。(记住,这里nums.append(x)并没有改变nums,它返回了一个新的列表,附加了x。但是这个新列表不会保存在任何地方。)

我们必须这样编写foo例程:

1
2
3
4
5
def foo():
  nums = []
  for x in range(0,10):
    nums = nums.append(x)
  return nums

(事实上,这非常类似于在大约2.6或2.5之前使用python字符串的情况。)

此外,每次我们分配nums = nums.append(x)时,我们都会复制一个不断增大的列表,从而导致二次型行为。出于这些原因,我们列出了可变对象。

使列表可变的结果是在这些语句之后:

1
2
3
a = [1,2,3]
b = a
a.append(4)

清单B改为[1,2,3,4]。这是我们生活在一起的东西,尽管它不时地让我们感到困惑。


让数字在Python中不可变的设计决策是什么?

不可变有几个原因,让我们先看看不可变的原因是什么?

1存储器

  • 节省内存。如果众所周知一个对象是不可变的,那么可以很容易地复制它,从而创建对同一对象的新引用。
  • 性能。python可以在创建时为不可变对象分配空间,存储需求是固定不变的。

2-快速执行。

  • 它不需要复制对象的每个部分,只需要一个简单的引用。
  • 比较容易,通过引用比较相等比通过值比较快。

3 -安全性:

  • 在多线程应用程序中,不同的线程可以与不可变对象中包含的数据进行交互,而无需担心数据的一致性。
  • 即使您有异常,程序的内部状态也将是一致的。
  • 类应该是不可变的,除非有非常好的理由使它们可变……如果类不能成为不可变的,请尽可能限制其可变性

4 -易于使用

  • 更容易阅读,更容易维护,也不太可能以奇怪和不可预测的方式失败。
  • 不可变对象更容易测试,这不仅是因为它们易于模仿,而且还因为它们倾向于强制执行代码模式。

5-键必须是不可变的。这意味着您可以使用字符串、数字或元组作为字典键。这是你想用的东西。

1
The hash table implementation of dictionaries uses a hash value calculated from the key value to find the key. If the key were a mutable object, its value could change, and thus its hash could also change. But since whoever changes the key object can’t tell that it was being used as a dictionary key, it can’t move the entry around in the dictionary. Then, when you try to look up the same object in the dictionary it won’t be found because its hash value is different. If you tried to look up the old value it wouldn’t be found either, because the value of the object found in that hash bin would be different.

回到整数:

  • 安全性(3)、易用性(4)和在字典中使用数字作为键的能力(5)是决定数字不可变的原因。

  • 自创建时起具有固定的内存需求(1)。

  • 在python中,数字(如字符串)都是"元素"对象。任何活动量都不会将值8更改为其他值,任何活动量都不会将字符串"8"更改为其他值。这是因为设计中也有一个决定。