我最近在某处读到Nonepython中的特殊值是其所属类的singleton对象,尤其是NoneType。这解释了很多,因为大多数涉及Nonepython的错误都会产生AttributeErrors而不是一些特殊的“ NoneError”之类的东西。
None
NoneType
AttributeError
由于所有的这些AttributeErrors反映了属性的NoneType缺乏,我开始由什么属性感兴趣NoneType 并 如有有。
AttributeErrors
我决定调查一下NoneType并进一步了解。我一直发现学习新语言功能的最佳方法是使用它,因此我尝试NoneType在IDLE中实例化:
>>> n = NoneType()
这产生了一个错误:
Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> n = NoneType() NameError: name 'NoneType' is not defined
感到困惑,我检查None了类型名称是否正确。果然,
>>> type(None) <class 'NoneType'>
现在很困惑,我做了一个快速的谷歌搜索。这表明出于某种原因在Python 3中删除了NoneType。
好吧,我,哈哈!我可以通过将None变量的类型存储在变量中来解决此问题,因为类是python中的对象。这似乎可行:
>>> NoneType = type(None) >>> n = NoneType()
当我打印n时,我得到的是我所期望的:
>>> print(n) None
但是后来发生了:
>>> n is None True
和:
>>> id(n) 506768776 >>> id(None) 506768776
我的变量nIS None。不仅类型与相同None。是的None。这不是我所期望的。
n
我尝试使用dis获取有关的更多信息NoneType,但是当我打电话时
dis
>>> dis.dis(type(None))
它没有产生输出。
然后,我尝试研究该__new__方法,一些用户在评论中提到了该方法:
__new__
dis.dis(type(None).__new__) Traceback (most recent call last): File "<pyshell#4>", line 1, in <module> dis.dis(type(None).__new__) File "C:\Python33\lib\dis.py", line 59, in dis type(x).__name__) TypeError: don't know how to disassemble builtin_function_or_method objects >>>
更多错误。
这是我的问题:
为什么n对象与完全相同None?
C实现保留一个单例实例。 NoneType.__new__返回单例实例。
NoneType.__new__
为什么设计语言时要使n与Object完全相同None?
如果没有单例实例,则x is None由于is操作员基于身份,因此您不能依赖检查。尽管None == None也是如此True,但实际上可能x == None是True在何时。有关示例,请参见此答案。x``None)
x is None
is
None == None
True
x == None
x``None
一个人怎么会在python中实现这种行为呢?
您可以通过重写实现此模式__new__。这是一个基本示例:
class Singleton(object): _instance = None def __new__(cls, *args, **kwargs): if Singleton._instance is None: Singleton._instance = object.__new__(cls, *args, **kwargs) return Singleton._instance if __name__ == '__main__': s1 = Singleton() s2 = Singleton() print 's1 is s2:', s1 is s2 print 'id(s1):', id(s1) print 'id(s2):', id(s2)
输出:
s1是s2:真实 ID(s1):4506243152 id(s2):4506243152
当然,这个简单的示例不会使创建第二个实例成为 不可能 。