Python None比较:我应该使用“ is”还是==?


213

比较时我的编辑会警告我my_var == None,但使用时不会警告my_var is None

我在Python Shell中进行了测试,并确定两者都是有效的语法,但我的编辑器似乎在说这my_var is None是首选。

是这样吗?如果是这样,为什么?


7
PEP 8说的地方,你应该比较使用单身is- python.org/dev/peps/pep-0008/#programming-recommendations
波动率

2
那个海报谈论的是Python 3,我的问题是关于Python2.x。我不确定这是否有足够大的差异以保证剩余两个都可以,但是我编辑了问题以防万一。
Clay Wardell,2013年

2
我不认为这个问题确实是重复的。另一个大约是== vs,一般来说,这个大约是None。
IJ肯尼迪

Answers:


254

摘要:

使用is时要核对对象的身份(如检查,看看是否varNone)。使用==时要检查的平等(例如是var等于3?)。

说明:

您可以在其中my_var == None返回的自定义类True

例如:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

is检查对象身份。只有1个对象None,因此在执行操作时my_var is None,您要检查它们是否实际上是同一对象(而不仅仅是等效对象)

换句话说,==是检查等效性(定义在对象之间),而is检查对象身份:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

22
什么时候is None== None
Blender

11
@Blender在提到的情况下。__eq__可以以任何方式定义,但is不能轻易更改其行为。
Lev Levitsky

5
@LevLevitsky:Mython的示例用法之一是“扩展协议,以便任何运算符都可以重载,甚至is”。在对列表进行评论后,他将其更改为“…甚至is(但仅当您疯了时)”。
abarnert

1
+1,但如果此答案包含其他人也做过的PEP 8参考(以及解释为什么PEP 8做出的决定为什么有意义,它已经做到了),那就更好了。
abarnert

3
@abarnert-我什至都不知道PEP 8在这里提出了建议。关键是他们是做不同事情的不同运营商。在某些情况下,object == None实际上正确的成语(尽管我想不出什么来头)。您只需要知道自己在做什么。
mgilson

127

is通常,在将任意对象与单例对象进行比较时,通常首选,None因为它更快且更可预测。is总是按对象身份进行比较,而==做什么取决于操作数的确切类型,甚至取决于它们的顺序。

PEP 8对此建议提供了支持,该声明明确指出 “对单例的比较(如None,应始终使用isis not,绝不能使用相等运算符进行)”。


6
感谢您发布此信息;接受的答案提出了一些有趣的观点,但是您的回答则更加直接。
卢克·戴维斯

依靠本质上是实现细节的方法似乎很奇怪。我为什么要关心有多少个NoneType实例?
BallpointBen19年

@BallpointBen因为它不是实现细节,所以None在全局常量下只有一个对象None。如果有的话,这NoneType是实现细节,因为None单例必须具有某种类型。(无法创建此类型的实例的事实很好地表明了该实例的一个实例旨在成为单例。)
user4815162342

@BallpointBen我认为关键是Python具有强大的对象标识概念。如果要检查对象是否比较相等None,通过各种手段使用obj == None。如果要检查对象是否 None使用obj is None。PEP 8建议(以及此答案)的要点是,大多数人在想要检查“无”时都希望使用后者,并且碰巧更快,更清晰。
user4815162342

None与缓存的对象(例如0和其他小整数)也不同,在缓存中,缓存实际上是实现细节。所不同的是,整数具有固有值,该固有值给出了其属性并且可以计算得出。另一方面,None没有任何状态,只有它的身份才重要,并使它变得特殊。
user4815162342

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.