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

In python, why 'is' is preferred over '==' for checking if object in None

如果我这样写:

if x == None:
    x = 1

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

if x is None:
    x = 1

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

if x == 2:
    x = 1

为什么在检查对象是否为 None'is' 运算符优先于 '==' 运算符?

为什么只有 None 喜欢它?

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

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

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

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

class Devious(object):
    def __eq__(self, other):
        return other is None

现在您的 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

但如果您希望 None 成为有效值,您可以使用 不同的标记 :

_sentinel = object()

def foo(arg1, optional=_sentinel):
    if optional is _sentinel:
        # no value given for optional

现在您可以使用 foo(1, None),它会被正确地视为一个值。