Python中除了None之外还有哪些独特的实例对象?

4
Python语言参考中提到了三个具有单一,唯一实例的对象:NoneNotImplementedEllipsis(见第3.2节“标准类型层次结构”)。由于None的唯一性得到保证,测试x is None成为了一种常见的习惯用法。我在Python文档或Stack Overflow上没有找到其他关于唯一实例对象的提及。一些问题,如这个问题,提出了有趣的建议来构造这样的对象,但我想知道的是除了这三个内置对象之外,是否还有我错过的其他对象。
例如,在CPython中进行了非常有限的测试后,()似乎是唯一的,因此测试x is ()是否安全?还是说对于这种情况,x == ()是必须的?

测试 x is () 没有意义,if x 可以达到同样的效果。你为什么要问呢? - Padraic Cunningham
bool(x) 可能有许多值为 False。我需要检查 x 是否实际上是 (),而不是其他可能性之一,原因与您使用 x is None 相同。 - David Munro
如果 x 是一个元组,isinstance(x, tuple) 也可以明确地让你检查 x 是否确实是一个元组。 - Padraic Cunningham
看到这个,我意识到在某些情况下,当None是有效值(即从函数/方法请求的对象存在,但其值可以为None),而不是真正不存在对象时,我也可以返回NotImplemented(并使用'is'进行测试)以表示某些东西并不存在。 - wojtow
3个回答

2

好的...你可以把任何全局对象看作是“唯一”的,这意味着它始终是相同的对象。

例如:

>>> x = file
>>> x is file
True
>>> x = True
>>> x is True
True
>>> x = ZeroDivisionError
>>> x is ZeroDivisionError
True

关于这个问题,没有什么特别的:

>>> x = None
>>> x is None
True

您可能会想知道为什么应该测试x is None而不是x == None
答案是:x == None将调用x.__eq__(None),这可能会在很多情况下返回True,即使实际上x并不是None(虽然这种情况并不常见)。
实例?
嗯,您可能会说有所区别:None是一个实例。
事实是,Python中的所有东西都是对象,这意味着所有东西都是实例。在我的例子中,fileZeroDivisionErrortype的实例,Truebool的实例,NoneNoneType的实例(请注意,typetype的实例,因此没有例外)。
关于None有一个特殊之处-它是NoneType的唯一实例,您无法创建其他实例(除非有什么好的技巧?)
但这实际上是NoneType的一个属性-它不允许您创建新实例:
TypeError: cannot create 'NoneType' instances

但这并不是整个故事的关键。

编辑 这些“unique-instance objects”被称为单例。当然,你也可以创建自己的单例对象。


1

就这个问题而言,在PyPy 4.0.1中,()并不是唯一的。

>>>> x = ()
>>>> x is ()
False

1
他特别提到了CPython。 - user559633

1

没有其他内置类型具有单个值。这些单例的唯一亲戚是bool类型,它允许两个值(即TrueFalse)*。

Python 2.x中(我找不到它们在3.x中),您可以通过从types模块导入NotImplementedType、EllipsisType、NoneType并意识到它明确不是它的花哨自定义TypeError来看到这个限制:

In [13]: from types import NoneType

In [14]: n = NoneType()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-b386f51143fb> in <module>()
----> 1 n = NoneType()

TypeError: cannot create 'NoneType' instances

()不幸地不是唯一的,它代表一个空元组,如果类型TupleNoneType是唯一的意义上是唯一的,则所有实例都需要具有相同的值


如果您想更仔细地查看它们,它们位于Objects/object.c13511473行,分别对应于NoneNotImplemented。省略号尚未找到。
*更新:显然,根据PEP 285 - 添加bool类型TrueFalse也是单例模式:

像None一样,False和True的值将是单例。因为该类型有两个值,也许应该称之为“双子”?真正的实现将不允许创建其他bool实例。


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