“foo是None”还是“foo == None”有什么区别?
有什么区别:
if foo is None: pass
和
if foo == None: pass
我在大多数Python代码(以及我自己编写的代码)中看到的惯例是前者,但是最近我遇到了使用后者的代码。 没有一个是NoneType的一个实例(也是唯一的实例IIRC),所以没关系,对吗? 有没有可能的情况?
如果它比较相同的对象实例, is
总是返回True
而==
最终由__eq__()
方法确定
即
>>> class Foo(object): def __eq__(self, other): return True >>> f = Foo() >>> f == None True >>> f is None False
你可能想读这个对象的身份和等价 。
语句“is”用于对象标识,它检查对象是否引用同一个实例(内存中的相同地址)。
而'=='语句引用相等(相同的值)。
谨慎的一句话:
if foo: # do something
不完全相同:
if x is not None: # do something
前者是一个布尔值testing,可以在不同的上下文中评估为false。 在布尔值testing中有许多表示为false的东西,例如空容器,布尔值。 在这种情况下,没有人也评价为假,但其他的事情也是这样。
(ob1 is ob2)
等于(id(ob1) == id(ob2))
foo is None
的原因foo is None
首选的方法是,您可能正在处理一个定义其自己的__eq__
的对象,并将该对象定义为等于None。 因此,如果您需要查看是否为真,则始终使用foo is None
None
。
没有区别,因为相同的物体当然是相等的。 然而, PEP 8明确指出你应该使用的is
:
比较像None这样的单身人士应该总是用“是”或“不是”,而不是“平等”。
对于无,不应该有平等(==)和身份(是)之间的区别。 NoneType可能会返回相同的身份。 由于None是唯一可以做的NoneType(我认为这是真的),所以这两个操作是相同的。 在其他types的情况下,情况并非总是如此。 例如:
list1 = [1, 2, 3] list2 = [1, 2, 3] if list1==list2: print "Equal" if list1 is list2: print "Same"
这将打印“相等”,因为列表有一个比较操作,不是默认返回的身份。
// @ Jason :
我build议使用更多的东西
if foo: #foo isn't None else: #foo is None
我不喜欢用“if foo:”,除非foo真正代表布尔值(即0或1)。 如果foo是一个string或者一个对象或者其他的东西,“if foo:”可能会起作用,但是它看起来像是一个懒惰的快捷方式。 如果您检查x是否为None,请说“如果x是None:”。
is
testing身份, 而不是平等。 对于你的语句foo is none
,Python只是比较对象的内存地址。 这意味着你问的问题是:“我有两个同名对象的名字吗?”
==
另一方面testing由__eq__()
方法确定的相等性。 它不关心身份。
In [102]: x, y, z = 2, 2, 2.0 In [103]: id(x), id(y), id(z) Out[103]: (38641984, 38641984, 48420880) In [104]: x is y Out[104]: True In [105]: x == y Out[105]: True In [106]: x is z Out[106]: False In [107]: x == z Out[107]: True
None
一个是单身经营者。 所以None is None
是永远是真的。
In [101]: None is None Out[101]: True
约翰·马金(John Machin)的结论是“ None
是一个单独的结论。
>>> x = None >>> y = None >>> x == y True >>> x is y True >>>
由于None
是一个单独的,所以x == None
和x is None
将具有相同的结果。 不过,在我的美学观点中, x == None
是最好的。
一些更多细节:
-
is
子句实际上检查两个object
是否在同一个内存位置。 即它们是否都指向相同的内存位置并具有相同的id
。 -
作为1的结果,确保两个词汇表示的
object
是否具有相同的属性(属性的属性…)或不 -
像
bool
,int
,string
(具有一些例外)的原始types的实例化,具有相同值的NoneType
将总是在相同的存储器位置中。
例如
>>> int(1) is int(1) True >>> str("abcd") is str("abcd") True >>> bool(1) is bool(2) True >>> bool(0) is bool(0) True >>> bool(0) False >>> bool(1) True
而且由于NoneType
只能在python的“look-up”表中拥有自己的一个实例,所以前者和后者更像是编写代码的开发人员的编程风格(可能是为了一致性),而不是具有任何微妙的逻辑原因select一个在另一个之上。