在Python中,None是一个唯一的对象吗?

5
在我的测试代码中,为什么元组和空值的print结果不同?似乎a、b指向相同的None对象,但c、d指向不同的对象,尽管它们的值相同(都等于(a,b))。
我知道is关键字检查的是对象背后的内容而不仅仅是比较值,例如==。在这里我使用元组,因为我认为元组是不可变的,所以至少问题不在于对象是否可变。
但是为什么变量a、b没有像c、d那样创建并指向两个不同的None对象呢?
a=None
b=None
c=(1,2)
d=(1,2)
print(a is b)
print(c is d)
3个回答

7

None对象是Python中的单例。因此产生了这个结果。

而对于cd,它创建了不同的元组。

从你的例子中可以看出:

>>> id(None)
4454442584
>>> id(a)
4454442584
>>> id(b)
4454442584
>>> id(c)
4463917464
>>> id(d)
4463865584

7

None是一个单例对象:它只能存在一个实例。因此,引用None的对象始终具有相同的标识,并且两个或多个这样的对象始终会通过标识(对象相等性)测试:

>>> a = None
>>> b = None
>>> c = None
>>> a is b is c
True

同样适用于 TrueFalse
>>> d = True
>>> (a is b is c) is d # proof of concept only
True

确保一下,对于单例对象,你说像 None、True 和 False 这样的对象,基本上 is== 的作用是完全相同的吗?顺便说一句,谢谢。 - Nicholas
1
对于布尔值,使用==进行测试(或对象本身)就足够了,因为对象具有真和假的值。 c = 1将通过c == True(最好直接使用c,如if c:...),但不会通过c is True。请注意,只有在您打算检查标识而不是相等性时才使用is - Moses Koledoye
等等,自从什么时候 a is b is c 不再被解析为 (a is b) is c 了?我以为这只适用于普通的比较运算符。编辑:'a' in 'ab' in 'abc' 也是有效的。 - Eric
@Eric 比较操作 可以任意链接。添加分组括号会强制解释器先计算 () 中的项目,然后再计算其他项目。在链接比较操作时添加括号时需要更加小心。 - Moses Koledoye
@MosesKoledoye:in不在那个列表中,但仍然可以链接。 - Eric
@Eric 不一定。在这种情况下,“in”的行为是明确定义的。更像是:'ab'.__contains__('a') and 'abc'.__contains__('ab')。从左到右进行评估。 - Moses Koledoye

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接