geekdoc-python-zh/docs/askpython/difference-between-equal-to...

4.4 KiB
Raw Permalink Blame History

在 Python 中==和的区别在于

原文:https://www.askpython.com/python/examples/difference-between-equal-to-and-is

操作符==is在 Python 中执行非常相似的任务,但是它们彼此非常不同,并且处理一个非常有趣的概念:Python 如何在内存中存储变量。

理解==和 is 之间的区别

简单来说,

  • ==检查两个操作数的值,如果相同,则返回True,否则返回False
  • is检查两个操作数的对象 ID如果相同则返回True

但是什么是对象 ID 呢?每个对象在内存中被分配一个 ID两个变量可以指向同一个对象这给了它们相同的对象 ID。

让我们用列表来看看它们的区别:

lst1 = [1,2,3]
lst2 = [1,2,3]
print(lst1 == lst2)
print(lst1 is lst2)

lst2 = lst1
print()
print(lst1 is lst2)

输出:

True
False

True

在上面的例子中,最初,内存中有两个列表,但是它们拥有完全相同的值。

  • ==比较数值,因此运算返回True
  • 但是is检查它们是否指向同一个对象,这些列表实际上是不同的对象,所以返回False
  • 在这之后,我们使lst2等于lst1,这使得lst2指向lst1所指向的地方,于是,is返回True

所有这些对于整数来说是非常不同的,为了理解这一点,我们需要知道对象是如何存储在内存中的。

Python 中的内存分配

我们需要理解 Python 中对象的内存分配,以便在本教程中更进一步。

让我们举一个例子:

number = 10

在这里,我们知道number保存了值 10但是它是如何存储在内存中的呢在 Python 中,每个对象在内存中都有四个部分:

  1. Size–对于每个对象,保留 4 个字节来保存对象的大小。
  2. 引用计数–对于每个对象,保留 8 个字节,用于保存指向该对象的变量数量。所有这些对象都有这个对象的对象 ID。
  3. 对象类型–对于每个对象,保留 8 个字节,用于保存表示对象类型的信息。
  4. 对象值–另外 8 个字节为每个对象保留,它们保存对象的实际值。

现在,在上面的列表中,对象值和引用计数是这次讨论的重点。

因此,对于number = 10,内存中有一个对象,其对象值为 10引用计数为 1这意味着该对象的值为 10有一个变量指向它在我们的例子中是number

现在让我们像这样声明另一个变量:

number_2 = number
print(number == number_2)
print(number is number_2)

现在,内存中会发生一件非常有趣的事情,不会有新的对象被创建,number_2也会指向number所指向的地方,对象的引用计数会增加到 2。

因此,numbernumber_2将具有相同的对象 ID输出将是:

True
True

但是如果我们这样做呢?

num1 = 10
num2 = 10
print(num1 == num2)
print(num1 is num2)

在上面的示例中,输出将是:

True
True

从-5 到 256 的特殊数字

Python 认为从-5 到 256 的整数是常用的整数,因此这些整数的对象总是预定义的,您不能从内存中删除这些对象。

所以在 Python 代码的开始,所有这些对象的引用计数都是零,但是如果任何变量的值都在-5 到 256(包括-5 和 256)之间,那么就不会创建新的对象,所有的变量都会指向已经存在的对象。

所以在上面的代码中10 的对象已经在内存中了,前两行只是创建了指向同一个对象的变量。

因此,对于下面的代码:

num1 = 257
num2 = 257
print(num1 == num2)
print(num1 is num2)

输出将是:

True
False

这是因为 python 会在每次声明整数时为超出该范围的整数创建新的实例。注意,如果我们已经做了num2 = num1,那么无论num1的值是多少,它们都将指向同一个对象。

结论

在本教程中,我们看到了==is之间的区别,以及is如何有助于发现两个变量是否指向同一个内存位置。

我们还看到了从-5 到 256 的整数是如何缓存在内存中的,因为它们被认为是常用的(像'a''b'这样的字符也被类似地缓存),在这个范围内具有相同值的两个变量将指向同一个对象。