为什么Python中的整数是不可变的?

时间:2016-05-31 01:54:06

标签: python immutability mutable

我理解Python中可变对象和不可变对象之间的区别。我读了许多讨论差异的帖子。但是,我没有读到任何关于WHY整数是不可变对象的内容。

这是否存在原因?或者答案是“它就是这样”?

编辑:我被提示将此问题与其他问题“区分”,因为它似乎是之前提出的问题。但是,我相信我所要求的更多的是一个哲学上的Python问题,而不是一个技术性的Python问题。

Python中的“原始”对象(即字符串,布尔值,数字等)似乎是不可变的。我还注意到由基元(即dicts,列表,类)组成的派生数据类型是可变的。

无论对象是否可变,绘制线的位置是?原始与派生?

2 个答案:

答案 0 :(得分:16)

使整数可变是非常违反我们习惯使用它们的方式。

考虑以下代码片段:

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

执行这些分配后,我们希望 a 的值为1, b 的值为3.加法运算是从整数中创建一个新的整数值存储在 a 和整数2的实例中。 如果添加操作只是在 a 处取整数并且只是突变它,那么 a b 都将具有值3.

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

但是,有些情况下,更改数据结构更方便,更有效。我们假设list.append(x)没有修改list,但返回了list的新副本,附加了x。 然后像这样的函数:

def foo():
  nums = []
  for x in range(0,10):
    nums.append(x)
  return nums

只会返回空列表。 (请记住 - 此处nums.append(x)不会更改nums - 它会返回一个附加x的新列表。但是这个新列表并未保存在任何地方。)

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

def foo():
  nums = []
  for x in range(0,10):
    nums = nums.append(x)
  return nums

(事实上,这与Python字符串的情况非常相似,直到大约2.6或2.5。)

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

使列表可变的结果是在这些陈述之后:

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

列表 b 已更改为[1,2,3,4]。这是我们生活的东西,即使它仍然偶尔让我们失望。

答案 1 :(得分:5)

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

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

1- 记忆

  • 节省内存。如果众所周知对象是不可变的,则可以轻松复制该对象,从而创建对同一对象的新引用。
  • 性能。 Python可以在创建时为不可变对象分配空间,并且存储要求是固定且不变的。

2- 快速执行

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

3- 安全性

  • 在多线程应用程序中不同的线程可以与不可变对象中包含的数据进行交互,而不必担心数据的一致性。
  • 即使您有例外情况,程序的内部状态也会保持一致。
  • 类应该是不可变的,除非有一个很好的理由使它们变得可变....如果一个类不能变成不可变的,尽可能地限制它的可变性

4- 易于使用

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

5- Keys must be immutable 。这意味着您可以使用字符串,数字或元组作为字典键。这是你想要使用的东西。

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”更改为其他任何内容。这是因为decision in the design