Python中的两个variables具有相同的id,但不包含列表或元组

Python中的两个variables具有相同的id

 a = 10 b = 10 a is b >>> True 

如果我拿两个list

 a = [1, 2, 3] b = [1, 2, 3] a is b >>> False 

根据这个链接 Senderle回答说,不可变的对象引用有相同的ID和可变的对象像列表有不同的ID。

所以现在根据他的回答,元组应该有相同的ID – 意思是:

 a = (1, 2, 3) b = (1, 2, 3) a is b >>> False 

理想情况下,因为元组不可变,所以它应该返回True ,但是它返回False

什么是解释?

不可变的对象不具有相同的id ,事实上,对于您单独定义的任何types的对象,这是不正确的。 每当你用Python定义一个对象时,你就会用新的身份创build一个新的对象。

但小整数(-5到256之间)和小string(internedstring,具有特殊长度(通常less于20个字符))有一些例外,它们是单例并且具有相同的id (实际上是具有多个指针的一个对象)。 你可以检查这个事实如下:

 >>> 30 is 20 + 10 True >>> >>> 300 is 200 + 100 False >>> 'aa' * 2 is 'a' * 4 True >>> 'aa' * 20 is 'a' * 40 False 

而对于一个自定义对象:

 >>> class A: ... pass ... >>> A() is A() # Every time you create an instance you'll have a new instance with new identity False 

另外请注意, is运算符将检查对象的身份,而不是值。 如果你想检查你应该使用的值==

 >>> 300 == 3*100 True 

而且由于对元组(其他types)没有这样的规则,如果你定义了任意大小的两个相同的元组,他们将得到他们自己的id:

 >>> a = (1,) >>> b = (1,) >>> >>> a is b False 

请注意,即使在可变和不可变对象中定义它们,单例整数和实string的事实也是如此:

 >>> a = (100, 700, 400) >>> >>> b = (100, 700, 400) >>> >>> a[0] is b[0] True >>> a[1] is b[1] False 

不可变!=同一个对象。 *

一个不可变对象只是一个状态不能改变的对象; 这就是全部。 当一个新的对象被创build时, 一个新的地址将被分配给它 因此,检查地址是否相等将返回False

1 is 1"a" is "a"的事实返回True是由于Python执行整数caching和string实习 ,所以不要让它混淆你; 它与所讨论的对象是不可变的/不可变的无关。


*空的不可变对象确实指的是同一个对象,而且它们的确是返回true,不过这是一个特殊的实现。

看看这个代码:

 >>> a = (1, 2, 3) >>> b = (1, 2, 3) >>> c = a >>> id(a) 178153080L >>> id(b) 178098040L >>> id(c) 178153080L 

为了弄清楚为什么a is c被评估为Truea is b产生False我强烈build议你在线Python Python Tutor中一步一步地运行上面的代码片段。 内存中对象的graphics表示将为您提供对这个问题的更深入的了解(我附上了屏幕截图)。

在这里输入图像说明