由于“is not”的不当使用而导致的奇怪 Python 行为比较?
我(错误地?)在比较中使用了“不是”,并发现了这种奇怪的行为:
>>> 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
“is”不是检查值是否相等,而是检查两个变量是否指向对象的同一实例。
int
和string
对此感到困惑,因为is
和==
可能会给出相同的结果语言的内部结构是如何工作的。"is" is not a check of equality of value, but a check that two variables point to the same instance of an object.
int
s andstring
s are confusing for this asis
and==
can happen to give the same result due to how the internals of the language work.对于较小的数字,Python 会重用对象实例,但对于较大的数字,它会为它们创建新的实例。
看这个:
这就是为什么
a
是b
,但c
不是d.
For small numbers, Python is reusing the object instances, but for larger numbers, it creates new instances for them.
See this:
which is exactly why
a
isb
, butc
isn'td
.不要使用 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.
Int 是 python 中的一个对象,并且 python 默认缓存 [-5,256] 之间的小整数,因此在 [-5,256] 中使用 int 的地方,它们是相同的。
如果你声明的两个整数不在[-5,256]中,python将创建两个不同的对象(尽管它们具有相同的值)。
在您的情况下,使用
!=
来比较值是正确的方法。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.
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).
In your case, using
!=
instead to compare the value is the right way.要更多了解为什么会发生这种情况,请查看 Python-2.6.5/Objects/intobject.c:78:small_ints 数组和 Python-2.6.5/Objects/intobject.c:1292 python 源代码中的 :_PyInt_Init 函数。
列表也会发生类似的情况:
删除的列表不会被销毁。它们被重复使用
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:
Removed lists are not destroyed. They are reused