在python中,为什么'is'优先于'=='来检查None中的对象

Sal*_*wal 3 python comparison pycharm python-2.7 nonetype

如果我写这个:

if x == None:
    x = 1
Run Code Online (Sandbox Code Playgroud)

我的pyCharm编辑器一直建议我应该使用'is'而不是'==':

if x is None:
    x = 1
Run Code Online (Sandbox Code Playgroud)

对于任何其他相等检查,pyCharm不建议使用'is',如:

if x == 2:
    x = 1
Run Code Online (Sandbox Code Playgroud)

为什么'is'操作'=='员在检查对象是否优先时优先于操作员None

为什么它只适用于None

Mar*_*ers 8

因为None是单例,所以Python程序中只有一个对象副本.

is测试单个对象时速度更快,因为只有指针需要相等.==测试更多信息,在这种情况下,测试对象状态也需要相同.

如果您的x对象实现自定义object.__eq__()方法,这仍然会变得更加明显; 每次使用x == None时都会调用它,而x is None没有这样的钩子.这意味着每次进行相等性测试时,解释器必须执行更多Python代码.我是否已经提到过一个简单的指针相等测试(用于is)很快?

该钩子还使自定义类型可以声明自己等于None:

class Devious(object):
    def __eq__(self, other):
        return other is None
Run Code Online (Sandbox Code Playgroud)

现在你的x == None测试将是真实的,即使x实际上并非如此None,而是一个实例Devious.如果你真的想知道是否x设置了None,只能x is None检测到这种情况.

None不是唯一可以测试身份的对象.每当您需要知道给定名称是否引用特定对象而不是值时,您应该使用is.

例如,有时您需要允许None成为有效值,但是您想要检测是否指定任何值.通常你可以None用作哨兵来检测是否遗漏了一个参数:

def foo(arg1, optional=None):
    if optional is None:
        # no value given for optional
Run Code Online (Sandbox Code Playgroud)

但如果你想None成为一个有效的价值,你会使用不同的哨兵:

_sentinel = object()

def foo(arg1, optional=_sentinel):
    if optional is _sentinel:
        # no value given for optional
Run Code Online (Sandbox Code Playgroud)

现在你可以使用foo(1, None)它,它将被正确地视为一个值.