由于“is not”的不当使用而导致的奇怪 Python 行为比较?

发布于 2024-09-09 05:40:46 字数 414 浏览 4 评论 0原文

我(错误地?)在比较中使用了“不是”,并发现了这种奇怪的行为:

>>> a = 256
>>> b = int('256')
>>> c = 300
>>> d = int('300')
>>>
>>> a is not b
False
>>> c is not d
True

显然我应该使用:

>>> a != b
False
>>> c != d
False

但由于测试用例价值较小,它工作了很长时间,直到我碰巧 使用数字 495。

如果这是无效语法,那么为什么?难道我不应该至少得到一个警告吗?

I (incorrectly?) used 'is not' in a comparison and found this curious behavior:

>>> a = 256
>>> b = int('256')
>>> c = 300
>>> d = int('300')
>>>
>>> a is not b
False
>>> c is not d
True

Obviously I should have used:

>>> a != b
False
>>> c != d
False

But it worked for a long time due to small-valued test-cases until I happened to
use a number of 495.

If this is invalid syntax, then why? And shouldn't I at least get a warning?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我的影子我的梦 2024-09-16 05:40:46

“is”不是检查值是否相等,而是检查两个变量是否指向对象的同一实例。

intstring 对此感到困惑,因为 is== 可能会给出相同的结果语言的内部结构是如何工作的。

"is" is not a check of equality of value, but a check that two variables point to the same instance of an object.

ints and strings are confusing for this as is and == can happen to give the same result due to how the internals of the language work.

不寐倦长更 2024-09-16 05:40:46

对于较小的数字,Python 会重用对象实例,但对于较大的数字,它会为它们创建新的实例。

看这个:

>>> a=256
>>> b=int('256')
>>> c=300       
>>> d=int('300')

>>> id(a)
158013588
>>> id(b)
158013588
>>> id(c)
158151472
>>> id(d)
158151436

这就是为什么 ab,但 c 不是 d.

For small numbers, Python is reusing the object instances, but for larger numbers, it creates new instances for them.

See this:

>>> a=256
>>> b=int('256')
>>> c=300       
>>> d=int('300')

>>> id(a)
158013588
>>> id(b)
158013588
>>> id(c)
158151472
>>> id(d)
158151436

which is exactly why a is b, but c isn't d.

如果没有 2024-09-16 05:40:46

不要使用 is [not] 来比较整数;使用 == 和 != 代替。尽管由于优化,is 在当前的 CPython 中适用于少量数据,但它是不可靠的并且在语义上是错误的。语法本身是有效的,但警告的好处(必须在每次使用 is 时进行检查,并且对于 int 的子类可能会出现问题)可能不值得这么麻烦。

这在 SO 的其他地方有介绍,但我现在没有找到。

Don't use is [not] to compare integers; use == and != instead. Even though is works in current CPython for small numbers due to an optimization, it's unreliable and semantically wrong. The syntax itself is valid, but the benefits of a warning (which would have to be checked on every use of is and could be problematic with subclasses of int) are presumably not worth the trouble.

This is covered elsewhere on SO, but I didn't find it just now.

流年里的时光 2024-09-16 05:40:46

Int 是 python 中的一个对象,并且 python 默认缓存 [-5,256] 之间的小整数,因此在 [-5,256] 中使用 int 的地方,它们是相同的。

a = 256
b = 256

a is b # True

如果你声明的两个整数不在[-5,256]中,python将创建两个不同的对象(尽管它们具有相同的值)。

a = 257
b = 257

a is b # False

在您的情况下,使用 != 来比较值是正确的方法。

a = 257
b = 257

a != b # False

Int is an object in python, and python caches small integer between [-5,256] by default, so where you use int in [-5,256], they are identical.

a = 256
b = 256

a is b # True

If you declare two integers not in [-5,256], python will create two objects which are not the same(though they have the same value).

a = 257
b = 257

a is b # False

In your case, using != instead to compare the value is the right way.

a = 257
b = 257

a != b # False
日裸衫吸 2024-09-16 05:40:46

要更多了解为什么会发生这种情况,请查看 Python-2.6.5/Objects/intobject.c:78:small_ints 数组和 Python-2.6.5/Objects/intobject.c:1292 python 源代码中的 :_PyInt_Init 函数。

列表也会发生类似的情况:


>>> a = [12]
>>> id_a = id(a)
>>> del(a)
>>> id([1,2,34]) == id_a
True
>>> 

删除的列表不会被销毁。它们被重复使用

For more understanding why this occurs take a look to Python-2.6.5/Objects/intobject.c:78:small_ints array and Python-2.6.5/Objects/intobject.c:1292:_PyInt_Init function in python sources.

Also similar thing occurs with lists:


>>> a = [12]
>>> id_a = id(a)
>>> del(a)
>>> id([1,2,34]) == id_a
True
>>> 

Removed lists are not destroyed. They are reused

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文