为什么整数在 Python 中是不可变的?
Why are integers immutable in Python?
我了解 Python 中可变对象和不可变对象之间的区别。我已经阅读了许多讨论差异的帖子。但是,我还没有读到任何关于为什么整数是不可变对象的内容。
这有什么原因吗?或者答案是“就是这样”?
编辑:我从其他问题中得到 'differentiate' 这个问题的提示,因为它似乎是一个以前问过的问题。但是,我相信我要问的更多是哲学 Python 问题,而不是技术 Python 问题。
Python 中的 'primitive' 个对象(即字符串、布尔值、数字等)似乎是不可变的。我还注意到由原语(即字典、列表、类)组成的派生数据类型是可变的。
无论对象是否可变,这就是分界线吗?原始还是派生?
使整数可变与我们习惯使用它们的方式非常违反直觉。
考虑这个代码片段:
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
但 return 编辑了 list
的新副本并附加了 x
。
然后是这样的函数:
def foo():
nums = []
for x in range(0,10):
nums.append(x)
return nums
只是 return 空列表。 (记住 - 这里 nums.append(x)
不会改变 nums
- 它 return 是一个附加了 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)
时,我们都会复制一个列表,该列表的大小会增加,从而导致二次行为。
由于这些原因,我们制作了列表 mutable objects.
使列表可变的结果是在这些语句之后:
a = [1,2,3]
b = a
a.append(4)
列表 b 已更改为 [1,2,3,4]
。这是我们一直在忍受的事情,尽管它时不时也会让我们失望。
在 Python 中使数字不可变的设计决策是什么?
不可变的原因有几个,我们先看看不可变的原因有哪些?
1- 内存
- 节省内存。如果众所周知对象是不可变的,则可以轻松复制它,创建对同一对象的新引用。
- 性能。 Python可以在创建时为不可变对象分配space,并且存储要求是固定不变的。
2- 快速执行.
- 不必复制对象的每个部分,只需要简单的引用。
- 易于比较,通过引用比较相等比比较值更快。
3- 安全:
- 在多线程应用程序中,不同的线程可以与不可变对象中包含的数据进行交互,而不必担心数据的一致性。
- 即使你有异常,你的程序的内部状态也会保持一致。
- 类 应该是不可变的,除非有很好的理由让它们可变....如果 class 不能不可变,尽可能限制它的可变性
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中的所有内容都是对象,数字(如字符串)是"elemental"对象。再多的 activity 也不会将值 8 更改为其他值,再多的 activity 也不会将字符串“eight”更改为其他任何值。这是因为decision in the design太.
我了解 Python 中可变对象和不可变对象之间的区别。我已经阅读了许多讨论差异的帖子。但是,我还没有读到任何关于为什么整数是不可变对象的内容。
这有什么原因吗?或者答案是“就是这样”?
编辑:我从其他问题中得到 'differentiate' 这个问题的提示,因为它似乎是一个以前问过的问题。但是,我相信我要问的更多是哲学 Python 问题,而不是技术 Python 问题。
Python 中的 'primitive' 个对象(即字符串、布尔值、数字等)似乎是不可变的。我还注意到由原语(即字典、列表、类)组成的派生数据类型是可变的。
无论对象是否可变,这就是分界线吗?原始还是派生?
使整数可变与我们习惯使用它们的方式非常违反直觉。
考虑这个代码片段:
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
但 return 编辑了 list
的新副本并附加了 x
。
然后是这样的函数:
def foo():
nums = []
for x in range(0,10):
nums.append(x)
return nums
只是 return 空列表。 (记住 - 这里 nums.append(x)
不会改变 nums
- 它 return 是一个附加了 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)
时,我们都会复制一个列表,该列表的大小会增加,从而导致二次行为。
由于这些原因,我们制作了列表 mutable objects.
使列表可变的结果是在这些语句之后:
a = [1,2,3]
b = a
a.append(4)
列表 b 已更改为 [1,2,3,4]
。这是我们一直在忍受的事情,尽管它时不时也会让我们失望。
在 Python 中使数字不可变的设计决策是什么?
不可变的原因有几个,我们先看看不可变的原因有哪些?
1- 内存
- 节省内存。如果众所周知对象是不可变的,则可以轻松复制它,创建对同一对象的新引用。
- 性能。 Python可以在创建时为不可变对象分配space,并且存储要求是固定不变的。
2- 快速执行.
- 不必复制对象的每个部分,只需要简单的引用。
- 易于比较,通过引用比较相等比比较值更快。
3- 安全:
- 在多线程应用程序中,不同的线程可以与不可变对象中包含的数据进行交互,而不必担心数据的一致性。
- 即使你有异常,你的程序的内部状态也会保持一致。
- 类 应该是不可变的,除非有很好的理由让它们可变....如果 class 不能不可变,尽可能限制它的可变性
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中的所有内容都是对象,数字(如字符串)是"elemental"对象。再多的 activity 也不会将值 8 更改为其他值,再多的 activity 也不会将字符串“eight”更改为其他任何值。这是因为decision in the design太.