|
1
18
Java的特殊情况是一些值类型(包括整数),这样它们就可以按值存储(而不是像其他一切一样按对象引用存储)。Python不会对这类类型进行特殊处理,因此将n分配给许多条目 在一份列表中 (或其他普通的Python容器)不必复制。 编辑:请注意,引用始终指向 物体
我们从第一张打印中看到,列表中的两个条目
一
例如,一个1000个项目的容器,所有项目都是不同的小整数(每个项目的值可以容纳2个字节),将大约2000个字节的数据作为
编辑 :@ooboo的评论提出了很多合理的后续问题,与其试图在评论中压制详细的解释,我把它移到这里。
CPython将引用存储为指向PyObject的指针(用Java和C#编写的Jython和IronPython使用这些语言的隐式引用;用Python编写的PyPy具有非常灵活的后端,可以使用许多不同的策略)
语言规范完全允许Python实现尝试更微妙的优化技巧,只要它保持语义不变,但据我所知,目前还没有一种方法可以解决这个特定问题(你可以尝试破解PyPy后端,但如果检查int和非int的开销超过了希望的收益,也不要感到惊讶)。
这些是每个实现都可以完全允许做出的实现选择的示例,因为保留语义并不难(因此假设即使是3.1和3.2在这方面也可能表现不同)。 当你使用int字面量(或不可变类型的任何其他字面量),或产生此类类型结果的其他表达式时,由实现决定是无条件地创建该类型的新对象,还是花一些时间检查这些对象,看看是否有可以重用的现有对象。 在实践中,CPython(我相信其他实现,但我不太熟悉它们的内部)使用了一个足够 小
一种语言 它有几个实现,在很多这样的细节上可能(合法和正确地)有所不同——每个人,包括像我这样的书呆子,在谈论流行的C编码实现时,往往只说“Python”而不是“CPython”(除非在像这样的上下文中,语言和实现之间的区别至关重要;-)。然而,区别 是 非常重要,值得偶尔重复一次。 |
|
|
2
6
在第二个示例中,您存储了len(arr)不同的整数。现在,python必须为len(arr)整数分配存储空间,并在每个len(arr)槽中引用它们。 |
|
|
3
3
你只有一个变量n,但你创建了许多i**2。
事实上,Python将继续重用相同的值,即使重新计算,也只使用对它的引用。例如:
通常不会使用超过
然而,在以下情况下
i的每个值都会得到一个引用,因此会保存在内存中,与其他示例相比会占用大量内存。
|
|
|
4
0
在第一示例中,
|