可能重复:
When is the `==` operator not equivalent to the `is` operator? (Python)
我使用的是Python 2.x。
当我比较my_var == None
时,我的编辑器会给我一个“警告”下划线,但是当我使用my_var is None
时没有警告。
我在Python shell中进行了测试并确定两者都是有效的语法,但我的编辑器似乎在说my_var is None
是首选。
是这种情况,如果是,为什么?
答案 0 :(得分:213)
如果要检查对象的身份,请使用is
(例如,检查var
是否为None
)。如果要检查相等,请使用==
(例如,var
是否等于3
?)。
您可以拥有my_var == None
将返回True
e.g:
class Negator(object):
def __eq__(self,other):
return not other
thing = Negator()
print thing == None #True
print thing is None #False
is
检查对象身份。只有一个对象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
答案 1 :(得分:102)
is
之类的单例进行比较时,通常首选{p> None
,因为它更快,更可预测。 is
始终按对象标识进行比较,而==
将执行的操作取决于操作数的确切类型,甚至取决于它们的排序。
PEP 8支持此建议,其中explicitly states“应该始终使用is
或is not
与单身人士进行比较,而不是单位运算符。”
答案 2 :(得分:10)
PEP 8定义了在比较单身人士时最好使用is
运算符。
答案 3 :(得分:2)
我最近遇到了可能出错的地方。
import numpy as np
nparray = np.arange(4)
# Works
def foo_is(x=None):
if x is not None:
print(x[1])
foo_is()
foo_is(nparray)
# Code below raises
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
def foo_eq(x=None):
if x != None:
print(x[1])
foo_eq()
foo_eq(nparray)
我创建了一个函数,它可以选择将一个 numpy 数组作为参数,并在包含它之前进行更改。如果我使用不等式运算符 !=
测试其是否包含,则会引发 ValueError(请参阅上面的代码)。如果我使用 is not none
,代码可以正常工作。
答案 4 :(得分:0)
“==”与“is”不同的另一个例子。当您从数据库中提取信息并检查某个值是否存在时,结果将是一个值或 None。
看看下面的 if 和 else。当数据库返回“无”时,只有“是”有效。如果改为使用 ==,则 if 语句将不起作用,它会直接转到 else,即使结果为“无”。希望我说清楚了。
conn = sqlite3.connect('test.db')
c = conn.cursor()
row = itemID_box.get()
# pull data to be logged so that the deletion is recorded
query = "SELECT itemID, item, description FROM items WHERE itemID LIKE '%" + row + "%'"
c.execute(query)
result = c.fetchone()
if result is None:
# log the deletion in the app.log file
logging = logger('Error')
logging.info(f'The deletion of {row} failed.')
messagebox.showwarning("Warning", "The record number is invalid")
else:
# execute the deletion
c.execute("DELETE from items WHERE itemID = " + row)
itemID_box.delete(0, tk.END)
messagebox.showinfo("Warning", "The record has been deleted")
conn.commit()
conn.close()
答案 5 :(得分:-1)
我们可以以打印功能为例。看这里:
print(print())
print(None)
都输出无:
None
None
is
指的是实际的东西,不管它们是不是对象都没有。 Print 不是对象 none。
print(None is print)
print(None is None)
现在我们得到了想要的结果。
False
True
PEP 8 也提到了这一点,说“与 None 等单例的比较应该总是用 is 或 is not 来完成,永远不要使用相等运算符。”
is
也更快。