Python 在交互模式下不驻留字符串?
Python not interning strings when in interactive mode?
在 Python 互动会话中时:
In [1]: a = "my string"
In [2]: b = "my string"
In [3]: a == b
Out[3]: True
In [4]: a is b
Out[4]: False
In [5]: import sys
In [6]: print(sys.version)
3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609]
另一方面,当运行以下程序时:
#!/usr/bin/env python
import sys
def test():
a = "my string"
b = "my string"
print(a == b)
print(a is b)
if __name__ == "__main__":
test()
print(sys.version)
输出为:
True
True
3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609]
为什么a is b
上面两种情况的结果不一样?
我知道 this 答案(当然还有 ==
和 is
运算符之间的区别! 这就是重点问题!)但在第一种情况下 a
和 b
不是同一个对象吗? (interpeter?)因为它们指向相同的(不可变的)字符串?
因此控制台在创建两个字符串时会创建两个不同的对象,但是当 运行 单个函数中的代码时,解释器将重用相同字符串的内存位置。以下是检查您是否遇到这种情况的方法:
a = "my string"
b = "my string"
print id(a)
print id(b)
如果这两个id相同,则a is b
将returnTrue
,否则将returnFalse
看来你用的是anaconda,所以我在控制台里查了一下,发现了不同的id,然后在编辑器里写了一个函数,执行了,得到了相同的id。
注:既然知道了is
判断两个变量标签是否指向内存中的同一个对象,那么应该说is
应该谨慎使用。它通常用于比较单例,例如 None a is None
。所以不要用它来比较对象,使用==
,并且在创建类时实现__eq__
方法,这样就可以使用==
运算符。
再举个例子,这是string interning. See this question造成的
在您的示例中,CPython 会在模块中保留字符串常量,但不会在 REPL 中保留。
在 Python 互动会话中时:
In [1]: a = "my string"
In [2]: b = "my string"
In [3]: a == b
Out[3]: True
In [4]: a is b
Out[4]: False
In [5]: import sys
In [6]: print(sys.version)
3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609]
另一方面,当运行以下程序时:
#!/usr/bin/env python
import sys
def test():
a = "my string"
b = "my string"
print(a == b)
print(a is b)
if __name__ == "__main__":
test()
print(sys.version)
输出为:
True
True
3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609]
为什么a is b
上面两种情况的结果不一样?
我知道 this 答案(当然还有 ==
和 is
运算符之间的区别! 这就是重点问题!)但在第一种情况下 a
和 b
不是同一个对象吗? (interpeter?)因为它们指向相同的(不可变的)字符串?
因此控制台在创建两个字符串时会创建两个不同的对象,但是当 运行 单个函数中的代码时,解释器将重用相同字符串的内存位置。以下是检查您是否遇到这种情况的方法:
a = "my string"
b = "my string"
print id(a)
print id(b)
如果这两个id相同,则a is b
将returnTrue
,否则将returnFalse
看来你用的是anaconda,所以我在控制台里查了一下,发现了不同的id,然后在编辑器里写了一个函数,执行了,得到了相同的id。
注:既然知道了is
判断两个变量标签是否指向内存中的同一个对象,那么应该说is
应该谨慎使用。它通常用于比较单例,例如 None a is None
。所以不要用它来比较对象,使用==
,并且在创建类时实现__eq__
方法,这样就可以使用==
运算符。
再举个例子,这是string interning. See this question造成的
在您的示例中,CPython 会在模块中保留字符串常量,但不会在 REPL 中保留。