Python - 为什么在这种情况下 'is' 操作符返回 True?

3

我刚开始学习Python,所以我的问题可能很显然。但根据W3Schools的说法,只有在“is”运算符下,两个变量引用同一个对象时才相等。那么我的问题是,为什么下面的代码会返回True?我原本认为Python会为它们创建两个不同的内存位置。

a = 500
b = 500

print(a == b) # True
print(a is b) # True, why is this true?

1
很可能有一个常量池用于字面量。尝试运行一个循环,在某个时刻,is测试将返回false。 - Abhijit Sarkar
1
这个回答是否解决了您的问题?"=="和"is"有什么区别吗?" - veedata
在许多编程语言中,Int 是值变量而不是引用变量。我想这就是情况。 - zolty13
CPython以intern小整数而闻名,但我记得这是从-5到256.因此,如果您执行x = 255; x is 255,则会返回True,但如果您执行x = 1000; x is 1000,则会返回False.很可能在同一表达式中,CPython正在为相同的字面量重复使用整数。这种实现的怪异性是为什么警告您对某些不可变文字使用==而不是is。不可变对象的有效标识是它们的值,因此请使用== - BatWannaBe
3个回答

4

你确定这对于值500有效吗?

Python 3.8.10 (default, Jun  2 2021, 10:49:15)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 500
>>> b = 500
>>> a is b
False
>>> b = 100
>>> a = 100
>>> a is b
True
>>>

Python中的预分配

在Python启动时,Python3会保留一个整数对象数组,范围从-5到256。例如,对于int对象,使用了名为NSMALLPOSINTS和NSMALLNEGINTS的宏:

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
   can be shared.
   The integers that are saved are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif
#ifdef COUNT_ALLOCS
Py_ssize_t quick_int_allocs;
Py_ssize_t quick_neg_int_allocs;
#endif

这是什么意思?这意味着当你从-5到256的范围内创建一个int时,实际上是在引用现有的对象。
参考:https://medium.com/@kjowong/everything-is-an-object-in-python-928f2a7d3e15

在脚本中尝试一下,你会看到 True - user2357112
实际上是的,但这是一种类似的优化。我尝试过了,最初相同的值是相同的,但从250+250“计算”得出的结果再次为false,这是预期的。 - Mandraenke

0
通常这是一个优化问题。当您更改其中一个值时,它将会分裂(并占用内存中的2个位置)。

这是一种优化,但不是你所建议的那种。a = 100; b = 100; a is b 打印出 True。然后,是的,a = 500 会将其分裂,但是 a = 500; a = 100; a is b 再次打印出 True,分裂和未分裂。@Mandraenke 的答案是正确的。 - joanis

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接