NoneType 的实现、原因和细节 [英] Implementation of NoneType, Reasons and Details

查看:55
本文介绍了NoneType 的实现、原因和细节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在某处读到,python 中的特殊值 None 是它自己的类的单例对象,特别是 NoneType.这解释了很多,因为在 python 中涉及 None 的大多数错误产生 AttributeErrors 而不是一些特殊的NoneError"或其他东西.

由于所有这些 AttributeErrors 都反映了 NoneType 缺少的属性,我对 NoneType 做了什么 的属性很感兴趣> 有,如果有的话.

我决定研究这个 NoneType 并了解更多信息.我一直发现学习新语言特性的最好方法就是使用它,所以我尝试在 IDLE 中实例化 NoneType:

<预><代码>>>>n = NoneType()

这产生了一个错误:

回溯(最近一次调用最后一次):文件<pyshell#0>",第 1 行,在 <module> 中n = NoneType()NameError: name 'NoneType' 未定义

很困惑,我检查了 None 以查看我是否获得了正确的类型名称.果然,

<预><代码>>>>类型(无)

现在很困惑,我做了一个快速的谷歌搜索.这表明 出于某种原因,NoneType 在 Python 3 中以某种方式被删除了.

不过我,哈哈!我可以通过将 None 的类型存储在一个变量中来解决这个问题,因为 类是 Python 中的对象. 这似乎有效:

<预><代码>>>>无类型 = 类型(无)>>>n = NoneType()

当我打印 n 时,我得到了我所期望的:

<预><代码>>>>打印(n)没有任何

但后来发生了:

<预><代码>>>>n 是无真的

还有:

<预><代码>>>>编号(n)506768776>>>id(无)506768776

我的变量 nNone.不仅与 None 的类型相同.它是.这不是我所期望的.

我尝试使用 dis 来获取有关 NoneType 的更多信息,但是当我打电话时

<预><代码>>>>dis.dis(类型(无))

它没有产生任何输出.

然后我尝试调查了几个用户在评论中提到的 __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 对象>>>

更多错误.

这是我的问题:

  • 为什么 nNone 是完全相同的对象?
  • 为什么将语言设计为 nNone 是完全相同的对象?
  • 如何在 Python 中实现这种行为?

解决方案

为什么 nNone 是完全相同的对象?>

C 实现保留了一个单例实例.NoneType.__new__ 正在返回单例实例.

为什么将语言设计为 n 与 None 是完全相同的对象?

如果没有单例实例,则您不能依赖检查 x is None,因为 is 运算符基于身份.虽然 None == None 也是 True,但当 x == NoneTrue 时, 是可能的>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 AttributeErrors 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 as None?
  • Why was the language designed such that n is the exact same Object as None?
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆