3

通常,如果我为变量分配一些值,然后检查它们的 id,我希望它们是相同的,因为 python 本质上只是给我的对象一个“名称”。这可以在下面的代码中看到:

>>> a = 3
>>> id(a)
19845928
>>> id(3)
19845928

问题是当我对“名称”执行相同操作时

>>> __name__
'__main__'
>>> id(__name__)
19652416
>>> id('__main__')
19652448

id怎么可能不同,不应该一样吗?因为__name__也应该只是一个参考。

4

4 回答 4

5

id() 本质上给出了指向数据的内存指针。尽管字符串是不可变的,但不能保证它们会被实习。这意味着一些具有相同值的字符串具有不同的指针。

对于整数(尤其是小整数),指针将是相同的,因此您的3示例可以正常工作。


@KartikAnand:您检查“相同对象”的方式是有效的,尽管通常的方式是使用x is y. 问题是它们不是同一个对象,并且不能保证是。它们只是具有相同的值。请注意,当您这样做时,"__main__"您正在创建一个新对象。有时,python 会进行很好的优化并重新使用先前创建的具有相同值的字符串,但并非必须如此。


Kartik 的目标是“验证分配是否以某种方式引用并且对象不是动态创建的”。为此,请避免创建新对象(无字符串文字)。

>>> __name__
'__main__'
>>> x = __name__
>>> id(__name__)
3078339808L
>>> id(x)
3078339808L
>>> __name__ is x
True
于 2012-05-17T16:03:52.947 回答
4

仅仅因为两个字符串具有相同的值,并不意味着它们是同一个对象。这是完全预期的行为。

于 2012-05-17T16:02:40.297 回答
3

在 Python 中,小整数是“池化的”,因此所有小整数值都指向同一个对象。这对于字符串来说不是必须的。

无论如何,这是一个不应该依赖的实现细节。

于 2012-05-17T16:02:31.203 回答
0

您在这里遇到的事实是,原语是 Python 中的伪(或真实)单例。此外,查看字符串会掩盖问题,因为当字符串被实习时,值和 id 会成为副作用的同义词,因此某些具有值匹配的字符串将具有 id 匹配,而另一些则不会。尝试查看手工构建的对象,这样您就可以控制何时创建新实例,并且 id 与 value 变得更加明确。

于 2012-05-17T16:18:53.547 回答