Python 脚本和 Python IDLE 中的不同行为?
Different behavior in Python script and Python IDLE?
在 Python 空闲中:
>>> a=1.1
>>> b=1.1
>>> a is b
False
但是当我将代码放在脚本中并运行它时,我会得到不同的结果:
$cat t.py
a=1.1
b=1.1
print a is b
$python t.py
True
为什么会这样?我知道is
比较两个对象的id
,那么为什么两个对象的id在Pythonscript/IDLE中是same/unique?
我还发现,如果我使用小整数,例如 1
,而不是 1.1
,Python 脚本和 Python 空闲。为什么 small int 和 small float 有不同的行为?
我正在使用 CPython 2.7.5.
当Python执行脚本文件时,首先解析整个文件。您可以注意到,当您在某处引入语法错误时:无论它在哪里,它都会阻止任何行执行。
所以由于Python首先解析文件,文字可以有效地加载到内存中。由于 Python 知道这些是常量,因此表示这些常量值的所有变量都可以指向内存中的同一个对象。所以对象是共享的。
这适用于整数和浮点数,但也适用于字符串;即使存在需要先计算的常量表达式:
a = "foo"
b = "foo"
c = "fo" + "o"
print(a is b)
print(a is c)
现在在 IDLE 中,行为非常不同:作为交互式解释器,IDLE 分别执行每一行。所以 a = 1.1
和 b = 1.1
是在不同的上下文中执行的,这使得不可能(或者很难)弄清楚它们都共享相同的常量文字值并且可以共享内存。因此,解释器将分配两个不同的对象,这会导致使用 is
的身份检查失败。
对于小整数,情况有点不同。因为它们经常被使用,CPython 静态地存储一组整数(在 -5 到 256 之间的范围内)并使这些整数的每个值都指向同一个 int
对象。这就是为什么对于小整数会得到与任何其他对象不同的结果。另请参阅以下问题:
- "is" operator behaves unexpectedly with integers
- What's with the Integer Cache inside Python?
在 Python 空闲中:
>>> a=1.1
>>> b=1.1
>>> a is b
False
但是当我将代码放在脚本中并运行它时,我会得到不同的结果:
$cat t.py
a=1.1
b=1.1
print a is b
$python t.py
True
为什么会这样?我知道is
比较两个对象的id
,那么为什么两个对象的id在Pythonscript/IDLE中是same/unique?
我还发现,如果我使用小整数,例如 1
,而不是 1.1
,Python 脚本和 Python 空闲。为什么 small int 和 small float 有不同的行为?
我正在使用 CPython 2.7.5.
当Python执行脚本文件时,首先解析整个文件。您可以注意到,当您在某处引入语法错误时:无论它在哪里,它都会阻止任何行执行。
所以由于Python首先解析文件,文字可以有效地加载到内存中。由于 Python 知道这些是常量,因此表示这些常量值的所有变量都可以指向内存中的同一个对象。所以对象是共享的。
这适用于整数和浮点数,但也适用于字符串;即使存在需要先计算的常量表达式:
a = "foo"
b = "foo"
c = "fo" + "o"
print(a is b)
print(a is c)
现在在 IDLE 中,行为非常不同:作为交互式解释器,IDLE 分别执行每一行。所以 a = 1.1
和 b = 1.1
是在不同的上下文中执行的,这使得不可能(或者很难)弄清楚它们都共享相同的常量文字值并且可以共享内存。因此,解释器将分配两个不同的对象,这会导致使用 is
的身份检查失败。
对于小整数,情况有点不同。因为它们经常被使用,CPython 静态地存储一组整数(在 -5 到 256 之间的范围内)并使这些整数的每个值都指向同一个 int
对象。这就是为什么对于小整数会得到与任何其他对象不同的结果。另请参阅以下问题:
- "is" operator behaves unexpectedly with integers
- What's with the Integer Cache inside Python?