“ foo is None”和“ foo == None”之间有什么区别吗?

问题:“ foo is None”和“ foo == None”之间有什么区别吗?

之间有什么区别:

if foo is None: pass

if foo == None: pass

我在大多数Python代码(以及我自己编写的代码)中看到的约定是前者,但是最近我遇到了使用后者的代码。None是NoneType的一个实例(也是唯一的实例,IIRC),所以没关系,对吗?在任何情况下都有可能吗?

Is there any difference between:

if foo is None: pass

and

if foo == None: pass

The convention that I’ve seen in most Python code (and the code I myself write) is the former, but I recently came across code which uses the latter. None is an instance (and the only instance, IIRC) of NoneType, so it shouldn’t matter, right? Are there any circumstances in which it might?


回答 0

isTrue如果比较相同的对象实例,则始终返回

==最终由该__eq__()方法确定


>>> class Foo(object):
       def __eq__(self, other):
           return True

>>> f = Foo()
>>> f == None
True
>>> f is None
False

is always returns True if it compares the same object instance

Whereas == is ultimately determined by the __eq__() method

i.e.


>>> class Foo(object):
       def __eq__(self, other):
           return True

>>> f = Foo()
>>> f == None
True
>>> f is None
False

回答 1

您可能需要阅读此对象的标识和等效信息

语句“ is”用于对象标识,它检查对象是否引用相同的实例(内存中的相同地址)。

并且’==’语句引用相等(相同的值)。

You may want to read this object identity and equivalence.

The statement ‘is’ is used for object identity, it checks if objects refer to the same instance (same address in memory).

And the ‘==’ statement refers to equality (same value).


回答 2

请注意:

if foo:
  # do something

与以下内容完全相同:

if x is not None:
  # do something

前者是布尔值测试,可以在不同的上下文中评估为false。在布尔值测试中,有很多东西代表假,例如空容器,布尔值。在这种情况下,没有人会得出错误的结论,但是其他事情也会发生。

A word of caution:

if foo:
  # do something

Is not exactly the same as:

if x is not None:
  # do something

The former is a boolean value test and can evaluate to false in different contexts. There are a number of things that represent false in a boolean value tests for example empty containers, boolean values. None also evaluates to false in this situation but other things do too.


回答 3

(ob1 is ob2) 等于 (id(ob1) == id(ob2))

(ob1 is ob2) equal to (id(ob1) == id(ob2))


回答 4

原因foo is None是首选的方式是您可能正在处理一个定义了自己__eq__的对象,并且该对象定义为等于None。因此,foo is None如果需要查看它是否确实存在,请始终使用None

The reason foo is None is the preferred way is that you might be handling an object that defines its own __eq__, and that defines the object to be equal to None. So, always use foo is None if you need to see if it is infact None.


回答 5

没有区别是因为相同的对象当然是相等的。但是,PEP 8明确指出您应该使用is

与单例(如None)的比较应该始终使用is或not(而不是equals运算符)进行。

There is no difference because objects which are identical will of course be equal. However, PEP 8 clearly states you should use is:

Comparisons to singletons like None should always be done with is or is not, never the equality operators.


回答 6

is测试身份,而不是平等。对于您的声明foo is none,Python只是比较对象的内存地址。这意味着您要问的问题是“同一对象有两个名称吗?”

==另一方面,根据__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

is tests for identity, not equality. For your statement foo is none, Python simply compares the memory address of objects. It means you are asking the question “Do I have two names for the same object?”

== on the other hand tests for equality as determined by the __eq__() method. It doesn’t cares about identity.

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 is a singleton operator. So None is None is always true.

In [101]: None is None
Out[101]: True

回答 7

对于“无”,相等(==)和身份(is)之间不应有区别。NoneType可能返回相等性的标识。由于None是唯一可以使用NoneType的实例(我认为这是对的),因此两个操作是相同的。对于其他类型,情况并非总是如此。例如:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"

这将打印“等于”,因为列表具有比较操作,而不是默认返回标识。

For None there shouldn’t be a difference between equality (==) and identity (is). The NoneType probably returns identity for equality. Since None is the only instance you can make of NoneType (I think this is true), the two operations are the same. In the case of other types this is not always the case. For example:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"

This would print “Equal” since lists have a comparison operation that is not the default returning of identity.


回答 8

@ 杰森

我建议按照以下方式使用更多内容

if foo:
    #foo isn't None
else:
    #foo is None

我不喜欢使用“ if foo:”,除非foo真正表示一个布尔值(即0或1)。如果foo是字符串或对象或其他对象,则“ if foo:”可能有效,但对我来说似乎是一个懒惰的快捷方式。如果要检查x是否为None,请说“如果x为None:”。

@Jason:

I recommend using something more along the lines of

if foo:
    #foo isn't None
else:
    #foo is None

I don’t like using “if foo:” unless foo truly represents a boolean value (i.e. 0 or 1). If foo is a string or an object or something else, “if foo:” may work, but it looks like a lazy shortcut to me. If you’re checking to see if x is None, say “if x is None:”.


回答 9

一些更多的细节:

  1. is子句实际上检查两个objects是否在相同的内存位置。即它们是否都指向相同的内存位置并具有相同的id

  2. 作为1的结果,请is确保两个词法表示的objects是否具有相同的属性(attributes-of-attributes …)

  3. 原始类型等的实例boolintstring(有一些exceptions),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的“查找”表中只能有一个自己的实例,因此前者和后者更像是编写代码的开发人员的编程风格(也许是为了保持一致性),而不是出于任何逻辑上的原因选择一个。

Some more details:

  1. The is clause actually checks if the two objects are at the same memory location or not. i.e whether they both point to the same memory location and have the same id.

  2. As a consequence of 1, is ensures whether, or not, the two lexically represented objects have identical attributes (attributes-of-attributes…) or not

  3. Instantiation of primitive types like bool, int, string(with some exception), NoneType having a same value will always be in the same memory location.

E.g.

>>> 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

And since NoneType can only have one instance of itself in the python’s “look-up” table therefore the former and the latter are more of a programming style of the developer who wrote the code(maybe for consistency) rather then having any subtle logical reason to choose one over the other.


回答 10

约翰·马钦(John Machin)得出的结论None是单例,这一结论得到了该代码的支持。

>>> x = None
>>> y = None
>>> x == y
True
>>> x is y
True
>>> 

由于None是单身,x == None并且x is None将有同样的结果。但是,从我的美学观点来看,x == None是最好的。

John Machin’s conclusion that None is a singleton is a conclusion bolstered by this code.

>>> x = None
>>> y = None
>>> x == y
True
>>> x is y
True
>>> 

Since None is a singleton, x == None and x is None would have the same result. However, in my aesthetical opinion, x == None is best.


回答 11

a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True
a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True