为什么以下在Python中出现意外行为?
>>> a = 256
>>> b = 256
>>> a is b
True # This is an expected result
>>> a = 257
>>> b = 257
>>> a is b
False # What happened here? Why is this False?
>>> 257 is 257
True # Yet the literal numbers compare properly
Run Code Online (Sandbox Code Playgroud)
我使用的是Python 2.5.2.尝试一些不同版本的Python,似乎Python 2.3.3显示了99到100之间的上述行为.
基于以上所述,我可以假设Python在内部实现,使得"小"整数以不同于大整数的方式存储,is运算符可以区分.为什么泄漏抽象?当我不知道它们是否是数字时,比较两个任意对象以查看它们是否相同的更好的方法是什么?
该
is运营商不匹配变量的值,但这些实例本身.
它到底意味着什么?
我声明了两个变量命名x并y在两个变量中分配相同的值,但是当我使用is运算符时它返回false .
我需要澄清一下.这是我的代码.
x = [1, 2, 3]
y = [1, 2, 3]
print x is y #It prints false!
Run Code Online (Sandbox Code Playgroud) 我在python 2.7.6 REPL中玩,并遇到了这种行为.
>>> x = -10
>>> y = -10
>>> x is y
False
>>> x, y = [-10, -10]
>>> x is y
True
Run Code Online (Sandbox Code Playgroud)
看起来,析构化赋值为等效值返回相同的引用.为什么是这样?
我用分号"发现了奇怪的行为"; 在Python中.
>>> x=20000;y=20000
>>> x is y
True
>>> x=20000
>>> y=20000
>>> x is y
False
>>> x=20000;
>>> y=20000
>>> x is y
False
Run Code Online (Sandbox Code Playgroud)
为什么第一次测试返回"True",其他测试返回"False"?我的Python版本是3.6.5.
看完这个和这个,这是非常相似,我的问题,我仍然无法理解以下行为:
a = 257
b = 257
print(a is b) #False
a, b = 257, 257
print(a is b) #True
Run Code Online (Sandbox Code Playgroud)
打印时id(a),id(b)我可以看到在单独的行中分配值的变量具有不同的ID,而对于多个赋值,两个值具有相同的id:
a = 257
b = 257
print(id(a)) #139828809414512
print(id(b)) #139828809414224
a, b = 257, 257
print(id(a)) #139828809414416
print(id(b)) #139828809414416
Run Code Online (Sandbox Code Playgroud)
但是,通过说多个相同值的赋值总是创建指向同一个id的指针,从而解释这种行为是不可能的:
a, b = -1000, -1000
print(id(a)) #139828809414448
print(id(b)) #139828809414288
Run Code Online (Sandbox Code Playgroud)
是否有一个明确的规则,它解释了变量何时变得相同id而不是?
编辑
相关信息:此问题中的代码以交互模式运行(ipython3)
单元测试模块时遇到了一个令人困惑的问题.该模块实际上是铸造值,我想比较这些值.
是有区别的使用比较==和is(部分,我小心的区别)
>>> 0.0 is 0.0
True # as expected
>>> float(0.0) is 0.0
True # as expected
Run Code Online (Sandbox Code Playgroud)
正如预期到现在,但这是我的"问题":
>>> float(0) is 0.0
False
>>> float(0) is float(0)
False
Run Code Online (Sandbox Code Playgroud)
为什么?至少最后一个对我来说真的很困惑.内部表示float(0)和float(0.0)应该是平等的.与之比较==正如预期的那样.
python floating-point python-2.7 python-3.x python-internals
从这个链接我了解到了
当前实现为-5到256之间的所有整数保留一个整数对象数组,当您在该范围内创建一个int时,实际上只返回对现有对象的引用
但是当我尝试为我的会话提供一些示例时,我发现它在赋值和元组解包时表现不同.
这是片段,
Python 2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a,b = 300,300
>>> a is b
True
>>> c = 300
>>> d = 300
>>> c is d
False
>>>
Run Code Online (Sandbox Code Playgroud) 可能重复:
Python"is"运算符使用整数意外运行
昨晚做了什么奇怪的事情
if max_urls is 0:
max_urls = 10
Run Code Online (Sandbox Code Playgroud)
总是会返回false ...即使max_urls为0 ....它也是从数据库中分配的.当我做了一个
print type(max_urls)
Run Code Online (Sandbox Code Playgroud)
会回来的
<type 'long'> 0
Run Code Online (Sandbox Code Playgroud)
这似乎是正确的,但它总是会返回虚假.
如果我把它改成了
if max_urls == 0:
max_urls = 10
Run Code Online (Sandbox Code Playgroud)
那么当它为0时它最终会返回true.为什么==和之间的区别是?
我正在使用Anaconda(Python 3.6).
在交互模式下,我对正整数> 256进行了对象标识测试:
# Interactive test 1
>>> x = 1000
>>> y = 1000
>>> x is y
False
Run Code Online (Sandbox Code Playgroud)
显然,在单独的行中写入的大整数(> 256)不会在交互模式下重复使用.
但是如果我们在一行中编写赋值,则重用大的正整数对象:
# Interactive test 2
>>> x, y = 1000, 1000
>>> x is y
True
Run Code Online (Sandbox Code Playgroud)
也就是说,在交互模式下,在一行或单独的行中写入整数赋值会对重用整数对象(> 256)产生影响.对于[-5,256]中的整数(如https://docs.python.org/2/c-api/int.html所述),缓存机制确保只创建一个对象,无论赋值是否相同或不同的线条.
现在让我们考虑小于-5的小负整数(任何超出范围[-5,256]的负整数都可以达到目的),出现了令人惊讶的结果:
# Interactive test 3
>>> x, y = -6, -6
>>> x is y
False # inconsistent with the large positive integer 1000
>>> -6 is -6
False
>>> id(-6), id(-6), id(-6)
(2280334806256, 2280334806128, 2280334806448)
>>> …Run Code Online (Sandbox Code Playgroud) x=300
y=300
print(id(x),id(y))
a=[300,300]
print(id(a[0]),id(a[1]))
Run Code Online (Sandbox Code Playgroud)
在上面的代码执行我得到不同的地址x和y,但相同的地址a[0]和a[1].谁能告诉我为什么会这样?
python ×10
python-3.x ×4
operators ×2
python-2.7 ×2
cpython ×1
identity ×1
int ×1
integer ×1
variables ×1