元组拆包与正常分配有何不同?

时间:2013-12-22 12:26:06

标签: python python-2.7 cpython

this link我学到了

  

当前实现为-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
>>>  

2 个答案:

答案 0 :(得分:7)

因为int是不可变的,所以Python可能会也可能不会使用exists对象,如果将以下代码保存到脚本文件中,并运行它,它将输出两个True。

a, b = 300, 300
print a is b

c = 300
d = 300
print c is d

当Python编译代码时,它可能会重用所有常量。假设您在python会话中输入代码,代码是逐行编译的,Python不能将所有常量重用为一个对象。

该文档仅说明只有一个实例为-5到256,但没有定义其他实例。对于不可变类型,isis not并不重要,因为您无法修改它们。

答案 1 :(得分:2)

 import dis

 def testMethod1():
     a, b = 300, 300

 print dis.dis(testMethod1)

打印:

  

4 0 LOAD_CONST 2((300,300))
                3 UNPACK_SEQUENCE 2
                6 STORE_FAST 0(a)
                9 STORE_FAST 1(b)
               12 LOAD_CONST 0(无)
               15 RETURN_VALUE无

 def testMethod2():
     a = 300
     b = 300

打印:

  

7 0 LOAD_CONST 1(300)
                3 STORE_FAST 0(a)
    8 6 LOAD_CONST 1(300)
                9 STORE_FAST 1(b)
               12 LOAD_CONST 0(无)
               15 RETURN_VALUE无

所以,它看起来基本相同,但在第一个方法的一个步骤中使用LOAD_CONST,在第二个方法中使用两个步骤....

修改
经过一些测试,我发现两种方法最终都会返回False;但是,仅在一次运行中,即不将方法放在循环中,它们似乎总是返回True。有时它使用单个引用,有时它不使用。

文档仅指出-5到256将返回相同的引用;因此,您只是不应该使用is进行比较(在这种情况下),因为数字的当前id无法保证。

注意:您永远不想使用is来比较值,因为这不是它的用途,而是比较身份。我的观点是,当你超出定义的范围时,is的返回值并不总是True