NoneType 的实现、原因和细节 [英] Implementation of NoneType, Reasons and Details
问题描述
我最近在某处读到,python 中的特殊值 None
是它自己的类的单例对象,特别是 NoneType
.这解释了很多,因为在 python 中涉及 None
的大多数错误产生 AttributeError
s 而不是一些特殊的NoneError"或其他东西.
由于所有这些 AttributeErrors
都反映了 NoneType
缺少的属性,我对 NoneType
做了什么 的属性很感兴趣> 有,如果有的话.
我决定研究这个 NoneType
并了解更多信息.我一直发现学习新语言特性的最好方法就是使用它,所以我尝试在 IDLE 中实例化 NoneType
:
这产生了一个错误:
回溯(最近一次调用最后一次):文件<pyshell#0>",第 1 行,在 <module> 中n = NoneType()NameError: name 'NoneType' 未定义
很困惑,我检查了 None
以查看我是否获得了正确的类型名称.果然,
现在很困惑,我做了一个快速的谷歌搜索.这表明 出于某种原因,NoneType 在 Python 3 中以某种方式被删除了.
不过我,哈哈!我可以通过将 None
的类型存储在一个变量中来解决这个问题,因为 类是 Python 中的对象. 这似乎有效:
当我打印 n 时,我得到了我所期望的:
<预><代码>>>>打印(n)没有任何但后来发生了:
<预><代码>>>>n 是无真的还有:
<预><代码>>>>编号(n)506768776>>>id(无)506768776我的变量 n
是 None
.不仅与 None
的类型相同.它是无
.这不是我所期望的.
我尝试使用 dis
来获取有关 NoneType
的更多信息,但是当我打电话时
它没有产生任何输出.
然后我尝试调查了几个用户在评论中提到的 __new__
方法:
dis.dis(type(None).__new__)回溯(最近一次调用最后一次):文件<pyshell#4>",第 1 行,在 <module> 中dis.dis(type(None).__new__)文件C:\Python33\lib\dis.py",第 59 行,在 dis 中类型(x).__name__)类型错误:不知道如何反汇编 builtin_function_or_method 对象>>>
更多错误.
这是我的问题:
- 为什么
n
与None
是完全相同的对象? - 为什么将语言设计为
n
与None
是完全相同的对象? - 如何在 Python 中实现这种行为?
为什么 n
和 None
是完全相同的对象?>
C 实现保留了一个单例实例.NoneType.__new__
正在返回单例实例.
为什么将语言设计为 n 与 None
是完全相同的对象?
如果没有单例实例,则您不能依赖检查 x is None
,因为 is
运算符基于身份.虽然 None == None
也是 True
,但当 x == None
为 True
时, 是可能的>x
实际上不是 None
.有关示例,请参阅此答案.
如何在 python 中实现这种行为?
您可以通过覆盖 __new__
来实现此模式.这是一个基本示例:
class Singleton(object):_instance = 无def __new__(cls, *args, **kwargs):如果 Singleton._instance 为 None:Singleton._instance = object.__new__(cls, *args, **kwargs)返回 Singleton._instance如果 __name__ == '__main__':s1 = 单例()s2 = 单例()打印 's1 是 s2:', s1 是 s2打印 'id(s1):', id(s1)打印 'id(s2):', id(s2)
输出:
<块引用>s1 是 s2:真
id(s1): 4506243152
id(s2): 4506243152
当然,这个简单的例子不会使不可能创建第二个实例.
I recently read somewhere that the special value None
in python is a singleton object of its own class, specifically NoneType
. This explained a lot, since most errors involving None
in python produce AttributeError
s instead of some special "NoneError" or something.
Since all of these AttributeErrors
reflected the attributes that NoneType
lacked, I became intrigued by what attributes NoneType
did have, if any.
I decided to look into this NoneType
and learn more about it. I've always found the best way to learn about a new language feature is to use it, so I tried instantiating NoneType
in IDLE:
>>> n = NoneType()
This produced an error:
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
n = NoneType()
NameError: name 'NoneType' is not defined
Confused, I inspected None
to see if I'd gotten the type name correct. Sure enough,
>>> type(None)
<class 'NoneType'>
Now very confused, I did a quick google search. This revealed that for some reason NoneType was somehow removed in Python 3.
Well I though, ha ha! I can work around this by storing the type of None
in a variable, since classes are objects in python. This seemed to work:
>>> NoneType = type(None)
>>> n = NoneType()
And when I printed n, I got pretty much what I was expecting:
>>> print(n)
None
But then this happened:
>>> n is None
True
And:
>>> id(n)
506768776
>>> id(None)
506768776
My variable n
IS None
. Not only the same type as None
. It IS None
. This is not what I expected.
I tried using dis
to get more info on NoneType
, but when I called
>>> dis.dis(type(None))
It produced no output.
I then then tried investigating the __new__
method, which several users had mentioned in the comments:
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
>>>
More errors.
Here are my questions:
- Why is
n
the exact same Object asNone
? - Why was the language designed such that
n
is the exact same Object asNone
? - How would one even implement this behavior in python?
Why is n
the exact same Object as None
?
The C implementation keeps a singleton instance. NoneType.__new__
is returning the singleton instance.
Why was the language designed such that n is the exact same Object as None
?
If there was not a singleton instance, then you could not rely on the check x is None
since the is
operator is based on identity. Although None == None
is also True
, it's possible to have x == None
be True
when x
is not actually None
. See this answer for an example.
How would one even implement this behavior in python?
You can implement this pattern by overridding __new__
. Here's a basic example:
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)
Output:
s1 is s2: True
id(s1): 4506243152
id(s2): 4506243152
Of course this simple example doesn't make it impossible to create a second instance.
这篇关于NoneType 的实现、原因和细节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!