在Python中,为什么比起使用'==',使用'is'来检查对象是否为None更被推荐?
在Python中,为什么比起使用'==',使用'is'来检查对象是否为None更被推荐?
这个问题已经有了答案:
如果我写下这个:
if x == None: x = 1
我的pyCharm编辑器一直建议我使用\'is\'而不是\'==\':
if x is None: x = 1
对于任何其他等式判断,pyCharm都不建议使用\'is\',例如:
if x == 2: x = 1
为什么在检查对象是否为None
时,\'is\'
运算符比\'==\'
运算符更受欢迎?
为什么只有对于None
的情况是如此?
admin 更改状态以发布 2023年5月21日
因为None
是一个单例对象,在Python程序中只有一个副本。\n\nis
在测试单个对象时比较快,因为只有指针需要相等。==
测试更多的信息,在这种情况下,被测试的对象的状态也需要相同。\n\n如果你的x
对象实现了自定义object.__eq__()
方法,这种情况变得更加明显;每次使用x==None
时都会调用它,而x is None
没有这样的钩子。这意味着解释器每次执行相等性测试时都必须执行一些Python代码。我已经提到过一个简单的指针相等测试(用于is
)是快速的吗?\n\n这个钩子也使得自定义类型能够声明自己等于None
:\n\n
class Devious(object): def __eq__(self, other): return other is None
\n\n现在你的x==None
测试将是true,即使x
实际上不是None
,而是Devious
的一个实例。如果你真的想知道x
是否设置为None
,只有x is None
能够检测到这种情况。\n\nNone
不是唯一可以使用身份测试的对象。任何时候,当你需要知道一个给定的名称是否引用了一个特定的对象而不是一个值时,你应该使用is
。\n\n例如,有时你需要允许None
作为一个有效的值,但是你想检测到是否指定了值。通常你可以使用None
作为哨兵来检测参数是否被省略:\n\n
def foo(arg1, optional=None): if optional is None: # no value given for optional
\n\n但如果你希望None
作为一个有效的值,那么你需要使用不同的哨兵:\n\n
_sentinel = object() def foo(arg1, optional=_sentinel): if optional is _sentinel: # no value given for optional
\n\n现在你可以使用foo(1,None)
,它将被正确地当作一个值处理。