通常如果我为变量分配一些值,然后检查它们的id,我希望它们是相同的,因为python本质上只是给我的对象一个“名字”。这可以在下面的代码中看到:
>>> a = 3
>>> id(a)
19845928
>>> id(3)
19845928
问题是当我用“名称”
执行相同操作时>>> __name__
'__main__'
>>> id(__name__)
19652416
>>> id('__main__')
19652448
如果有不同的ID,它们应该不一样吗?因为__name__
也应该只是一个参考。
答案 0 :(得分:5)
id()基本上给出了数据的内存指针。虽然字符串是不可变的,但不保证它们是实例化的。这意味着一些具有相同值的字符串具有不同的指针。
对于整数(特别是小整数),指针将是相同的,因此您的3
示例工作正常。
@KartikAnand:你检查“同一个对象”的方式是有效的,尽管通常的方法是使用x is y
。问题是它们不是同一个对象,并不能保证。它们只是具有相同的价值。请注意,当您执行"__main__"
时,您将创建一个新对象。有时候python会做一个很好的优化并重新使用之前创建的相同值的字符串,但它不会 。
Kartik的目标是“验证赋值是否以某种方式引用,并且不会动态创建对象”。为此,请避免创建新对象(无字符串文字)。
>>> __name__
'__main__'
>>> x = __name__
>>> id(__name__)
3078339808L
>>> id(x)
3078339808L
>>> __name__ is x
True
答案 1 :(得分:4)
仅仅因为两个字符串具有相同的值,并不意味着它们是同一个对象。这是完全预期的行为。
答案 2 :(得分:3)
在Python中,小整数被“合并”,因此所有小整数值都指向同一个对象。对于字符串,这不是必需的。
无论如何,这是一个不应该依赖的实现细节。
答案 3 :(得分:0)
你在这里遇到的事实是基元是Python中的伪(或真实)单例。此外,查看字符串会使问题浮现,因为当字符串被中断时,value和id会成为副作用的同义词,因此一些值匹配的字符串将具有id匹配而其他字符串则不会。尝试查看手工构建的对象,然后控制何时创建新实例,并且id vs value变得更明确。