Python在交互模式下不是实习字符串?

时间:2017-01-24 22:09:45

标签: python string python-3.5 equality

在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运营商之间的差异!这就是问题的关键点!)但在第一种情况下,ab是不是同一个对象? (interpeter?)因为它们指向相同的(不可变的)字符串?

2 个答案:

答案 0 :(得分:8)

这是由string interning引起的。有关其他示例,请参阅this question

在您的示例中,CPython实现模块中的字符串常量,但不在REPL中。

答案 1 :(得分:1)

因此,控制台在创建两个字符串时会创建两个不同的对象,但是解释器在单个函数中运行代码时将重用相同字符串的内存位置。以下是检查是否发生这种情况的方法:

a = "my string"
b = "my string"

print id(a)
print id(b)

如果这两个ID相同,则a is b会返回True,否则会返回False

看起来你正在使用anaconda,所以我在控制台中检查了这个并找到了不同的id然后在编辑器中编写了一个函数并执行它并得到了相同的ID。

注意:现在我们知道is确定两个变量标签是否指向内存中的同一个对象,我应该说应该谨慎使用is。它通常用于比较像a is None这样的单身人士。因此,请不要使用它来比较对象,使用==,并在创建类时实现__eq__方法,以便您可以使用==运算符。