这两者有什么不同吗:
if foo is None: pass
和
if foo == None: pass
我看到大多数Python代码(包括我自己编写的代码)遵循前者的约定,但最近我遇到了使用后者的代码。 None是NoneType的实例(也是唯一的实例,如果我没记错的话),所以这应该没有关系,对吗?是否存在任何可能影响结果的情况?
这两者有什么不同吗:
if foo is None: pass
和
if foo == None: pass
我看到大多数Python代码(包括我自己编写的代码)遵循前者的约定,但最近我遇到了使用后者的代码。 None是NoneType的实例(也是唯一的实例,如果我没记错的话),所以这应该没有关系,对吗?是否存在任何可能影响结果的情况?
is
如果比较的是同一个对象实例,总是返回True
,而==
则由__eq__()
方法决定。
即
>>> class Foo:
def __eq__(self, other):
return True
>>> f = Foo()
>>> f == None
True
>>> f is None
False
is
运算符无法被用户定义的类重载。 - martineau__eq__(self)
是一个特殊的内置方法,用于确定在Python对象上使用==
时如何处理。在这里,我们已经重写了它,以便当在类型为Foo
的对象上使用==
时,它总是返回true。对于is
运算符没有等效的方法,因此无法以同样的方式更改is
的行为。 - Brendana=1;b=1;print(a is b) # True
。你有什么想法,为什么即使它们似乎是两个不同的对象(在内存中具有不同的地址),a is b
的结果也为真? - Johnny Chiuif foo:
# do something
if foo is not None:
# do something
None
也会评估为false,但其他事物也会如此。foo is None
是首选的原因在于,您可能正在处理定义了自己的 __eq__
,并将对象定义为等于 None
的对象。因此,如果需要查看它是否实际上是 None
,始终使用 foo is None
。
is
版本不需要函数调用,也不需要任何 Python 解释器属性查找;如果 ob1 实际上就是 ob2,解释器可以立即回答。 - u0b34a0f6ae{}为{}
"是错误的,而"id({}) == id({})
"可以是(在CPython中确实如此)。请参见https://dev59.com/i2865IYBdhLWcg3wTc3h。 - Piotr Dobrogost没有区别,因为相同的对象自然会相等。然而,PEP 8明确规定你应该使用 is
:
与单例对象(如None)的比较应该始终使用is或is not,永远不要使用等于操作符。
is
用于测试身份(identity),而不是相等(equality)。对于语句foo is none
,Python只比较对象的内存地址。这意味着你正在问问题 "我是否有两个名称指向同一个对象?"
另一方面,==
测试等式,由 __eq__()
方法确定。它不关心身份(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
是一个单例操作符。因此None is None
总是为真。
In [101]: None is None
Out[101]: True
对于None来说,等于(==)和恒等(is)之间不应该有差别。NoneType类型可能会在等于操作中返回恒等。由于None是唯一的可以创建NoneType实例的对象(我认为是这样的),所以这两个操作是相同的。但对于其他类型来说,情况并非总是如此。例如:
list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"
@Jason:
I recommend using something more along the lines of
if foo: #foo isn't None else: #foo is None
我不喜欢使用 "if foo:",除非 foo 真的表示布尔值(即 0 或 1)。如果 foo 是字符串、对象或其他什么东西,"if foo:" 可能会起作用,但在我看来,它看起来像是一种懒惰的捷径。如果你想检查 x 是否为 None,请说 "if x is None:"。
if foo
将返回false,注释#foo is None
是错误的。 - blokeley更多细节:
is
子句实际上检查两个object
是否位于同一内存位置。也就是说,它们是否指向相同的内存位置并具有相同的id
。
由于1的影响,is
可以确保两个在词法上表示的object
是否具有相同的属性(属性-属性...)或不具有相同的属性。
原始类型的实例化,例如bool
、int
、string
(有一些例外)、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_string is "bar"
来比较字符串。没有任何可以接受的理由这样做,并且当你不期望时会出现错误。它通常能正常工作只是因为 CPython 知道创建两个具有相同内容的不可变对象是愚蠢的。但这种情况仍然可能发生。 - ThiefMasterint
,对吗? - Bleeding Fingers