在 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)
,它会被正确地视为一个值。
如果我这样写:
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)
,它会被正确地视为一个值。