Python无比较:我应该使用“是”还是==?

时间:2013-01-09 22:06:59

标签: python comparison nonetype

  

可能重复:
  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是首选。

是这种情况,如果是,为什么?

6 个答案:

答案 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“应该始终使用isis 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 也更快。