Python - 为啥在这种情况下“is”运算符返回 true? [复制]

Posted

技术标签:

【中文标题】Python - 为啥在这种情况下“is”运算符返回 true? [复制]【英文标题】:Python - Why is the 'is' operator returning true in this situation? [duplicate]Python - 为什么在这种情况下“is”运算符返回 true? [复制] 【发布时间】:2021-12-03 22:55:18 【问题描述】:

我是 Python 新手,所以我的问题似乎很明显。但是根据 W3Schools 的说法,如果两个变量引用同一个对象,则它们仅在“is”运算符下是相同的。所以我的问题是,为什么跟随返回 True?我以为 Python 会为它们创建两个单独的内存位置?

a = 500
b = 500

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

【问题讨论】:

很可能有一个常量池用于存放文字。尝试运行一个循环,在某些时候,is 测试将返回 false。 这能回答你的问题吗? Is there a difference between "==" and "is"? 在许多语言中,Int 是值变量而不是引用变量。我想是这样的 CPython 以实习小整数而闻名,但那是从 -5 到 256 iirc。所以如果你做x = 255; x is 255,你会得到True,但如果你做x = 1000; x is 1000,你会得到False。很可能在同一个表达式中,CPython 将整数重用于相同的文字。这种实现的怪异之处就是为什么警告您对某些不可变的文字执行 == 而不是 is 的原因。不可变对象的有效标识是它们的值,所以使用== 【参考方案1】:

这通常是一个优化问题。当你改变其中一个值时它会分裂(并占据内存中的 2 个位置)

【讨论】:

这是一种优化,是的,但不是您建议的。 a = 100; b = 100; a is b 打印 True。然后,是的,a = 500 将拆分它,但 a = 500; a = 100; a is b 再次打印 True,拆分和取消拆分。 @Mandraenke 的答案是正确的。【参考方案2】:

你确定这适用于价值 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 的 marcos:

#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 事实上是的,但它是一种类似的优化。尝试过,相同的值一开始是相同的,但是从 250+250 开始“计算”它又是预期的错误。【参考方案3】:

Python 中 == 和 is 运算符的区别 相等运算符 (==) 比较两个操作数的值并检查值是否相等。而“is”运算符检查两个操作数是否引用同一个对象(存在于同一个内存位置)

参考: https://www.geeksforgeeks.org/difference-operator-python/#:~:text=The%20Equality%20operator%20(%3D%3D),in%20the%20same%20memory%20location)。

【讨论】:

以上是关于Python - 为啥在这种情况下“is”运算符返回 true? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

python3在pycharm中为啥导入random模块不能用? TypeError: 'module' object is not callable

为啥在这种情况下需要使用 *this 返回对象引用? [复制]

为啥 Python 将单字符字符串视为相同? [复制]

SQL中 为啥要避免在where后使用'1=1'这种表达式作为部分条件

为啥 is 运算符在给定 null 时返回 false?

在python中出现这种情况为啥