【发布时间】:2014-10-08 12:13:13
【问题描述】:
Python docs 提到以下关于名称是对象的别名:
对象具有个体性,多个名称(在多个范围内)可以绑定到同一个对象。这在其他语言中称为别名。乍一看 Python 通常不会意识到这一点,在处理不可变的基本类型(数字、字符串、元组)时可以安全地忽略它。然而,别名对涉及可变对象(如列表、字典和大多数其他类型)的 Python 代码的语义可能产生令人惊讶的影响。这通常用于程序的好处,因为别名在某些方面表现得像指针。例如,传递一个对象很便宜,因为实现只传递了一个指针;如果一个函数修改了作为参数传递的对象,调用者将看到变化——这消除了对 Pascal 中两种不同的参数传递机制的需要。
在其他一些高级语言中,出于性能原因,原始类型通常是特殊类型的,并且是被复制而不是引用的。例如,在 Java 中:
int a = 20000;
int b = a;
上面的代码将复制值20000,而不是指向值20000 的指针。在这种情况下,a 和b 可能会占用内存中的不同位置。由于== 上的特殊情况仅用于测试原始类型的相等性而不是身份,但是我不相信这种行为可以在普通代码中进行自省。
另一方面,在 Python 3 中对 int 和 str 等类型的有限测试表明,确实复制的是指针而不是文档中指定的值:
a = 20000
b = a
a is b # True
这是一个非常好的属性,它使语言非常一致,因为原始类型没有特殊情况。所有分配都将名称重新分配给另一个对象。但是,出于性能原因,Python 解释器是否可以处理特殊情况类型,例如 int?
因此,我的问题是:原始类型的此属性是否得到保证?换句话说,无论使用哪种 Python 解释器,在b = a 之后,比较 a is b 是否总是真的是True?
【问题讨论】:
-
“保证跨解释器”在 Python 中可能是一件棘手的事情,因为该语言的许多微妙方面都没有明确说明。 (我不确定这是否是其中之一,可能不是。)
-
名称-对象绑定不是 Python 实现的一个微妙方面,而是该语言的基本原则。
-
"上面的代码将复制值 20000,而不是指向值 20000 的指针。"但两者在语义上没有区别。 “在这种情况下,a 和 b 可能会占据内存中的不同位置。”如果
a和b是引用类型Integer也是如此——变量a和b,它们是引用(指针)在内存中占据不同的位置;他们只是指向同一个对象。同样的事情发生在 Python 中。变量a和b在内存中占据不同的位置;它们只是指向同一个对象。