简体   繁体   English

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

[英]Is there any difference between “foo is None” and “foo == None”?

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. 我在大多数Python代码(以及我自己编写的代码)中看到的约定是前者,但我最近遇到了使用后者的代码。 None is an instance (and the only instance, IIRC) of NoneType, so it shouldn't matter, right? None是NoneType的实例(也是唯一的实例,IIRC),所以没关系,对吧? Are there any circumstances in which it might? 它有什么可能的情况吗?

is always returns True if it compares the same object instance 如果它比较同一个对象实例, is始终返回True

Whereas == is ultimately determined by the __eq__() method ==最终由__eq__()方法决定

ie


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

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

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). 语句'is'用于对象标识,它检查对象是否引用同一个实例(内存中的相同地址)。

And the '==' statement refers to equality (same value). '=='语句指的是相等(相同的值)。

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. 前者是布尔值测试,可以在不同的上下文中评估为false。 There are a number of things that represent false in a boolean value tests for example empty containers, boolean values. 在布尔值测试中有许多表示false的东西,例如空容器,布尔值。 None also evaluates to false in this situation but other things do too. 在这种情况下,None也评估为false,但其他事情也是如此。

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. foo is None的原因foo is None首选方法是您可能正在处理定义自己的__eq__的对象,并将对象定义为None。 So, always use foo is None if you need to see if it is infact None . 因此,如果您需要查看它是否foo is None ,则始终使用foo is None None

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

There is no difference because objects which are identical will of course be equal. 没有区别,因为相同的对象当然是相同的。 However, PEP 8 clearly states you should use is : 但是, PEP 8明确指出你应该使用的is

Comparisons to singletons like None should always be done with is or is not, never the equality operators. 像None这样的单例的比较应该总是使用is或者不是,而不是相等的运算符。

is tests for identity, not equality. is对身份的测试, 而不是平等。 For your statement foo is none , Python simply compares the memory address of objects. 对于你的语句foo is none ,Python只是比较对象的内存地址。 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. ==另一方面,由__eq__()方法确定的相等性测试。 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. None是单身操作员。 So None is None is always true. 所以None is None一直是真的。

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

For None there shouldn't be a difference between equality (==) and identity (is). 对于None,等于(==)和identity(是)之间不应该有区别。 The NoneType probably returns identity for equality. NoneType可能返回相等的标识。 Since None is the only instance you can make of NoneType (I think this is true), the two operations are the same. 由于None是唯一可以使用NoneType的实例(我认为这是真的),因此两个操作是相同的。 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. 这将打印“Equal”,因为列表的比较操作不是默认的身份返回。

@ 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 (ie 0 or 1). 我不喜欢使用“if foo:”,除非foo真正代表一个布尔值(即0或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. 如果foo是一个字符串或一个对象或其他东西,“if foo:”可能会起作用,但它看起来像是一个懒惰的快捷方式。 If you're checking to see if x is None, say "if x is None:". 如果您要检查x是否为None,请说“if x is None:”。

Some more details: 更多细节:

  1. The is clause actually checks if the two object s are at the same memory location or not. is子句实际上检查两个object是否在同一个内存位置。 ie whether they both point to the same memory location and have the same id . 即它们是否都指向相同的内存位置并具有相同的id

  2. As a consequence of 1, is ensures whether, or not, the two lexically represented object s have identical attributes (attributes-of-attributes...) or not 作为1的结果, is确保是否与否,两个词汇表示object ■找相同属性(属性-的的属性...)或不

  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. 原始类型的实例化(如boolintstring (有一些例外), NoneType具有相同的值将始终位于相同的内存位置。

Eg 例如

>>> 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. 并且由于NoneType在python的“查找”表中只能有一个自身实例,因此前者和后者更多地是编写代码的开发人员的编程风格(可能是为了一致性),而不是具有任何微妙的逻辑原因选择一个而不是另一个。

John Machin's conclusion that None is a singleton is a conclusion bolstered by this code. John Machin的结论是None是一个单身,这个结论得到了这个代码的支持。

>>> 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. 由于None是单例, x == Nonex is None将具有相同的结果。 However, in my aesthetical opinion, x == None is best. 但是,根据我的美学观点, x == None是最好的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM