python是带字符串的运算符行为

时间:2018-04-26 07:49:03

标签: python python-3.x identity python-internals

我无法理解以下行为。我正在创建2个字符串,并使用is运算符来比较它。在第一种情况下,它的工作方式不同。在第二种情况下,它按预期工作。我使用逗号或空格的原因是,与False比较时显示is,当没有使用逗号或空格或其他字符时,它会显示True

Python 3.6.5 (default, Mar 30 2018, 06:41:53) 
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 'string'
>>> b = a
>>> b is a
True
>>> b = 'string'
>>> b is a
True
>>> a = '1,2,3,4'
>>> b = a
>>> b is a
True
>>> b = '1,2,3,4'
>>> b is a
False

有没有关于python以不同方式解释字符串的原因的可靠信息?我理解,最初,ab指的是同一个对象。然后b获取一个新对象,b is aTrue。理解这种行为并不容易让人困惑。

当我使用'string'时,它会产生相同的结果。当我使用'1,2,3,4'时出了什么问题 - 它们都是字符串。与案例1和案例2有什么不同?即is运算符为字符串的不同内容产生不同的结果。

1 个答案:

答案 0 :(得分:9)

关于这种行为的一个重要的事情是Python缓存了一些主要是短字符串(通常少于20个字符,但不是每个字符串的组合),以便它们可以快速访问。其中一个重要原因是字符串在Pyhton的源代码中被广泛使用,它是一种内部优化,用于缓存一些特殊类型的字符串。字典是Python源代码中常用的数据结构之一,用于保存变量,属性和命名空间,以及其他一些用途,它们都使用字符串作为对象名称。这就是说,每次尝试访问对象属性或访问变量(本地或全局)时,都会在内部启动字典查找。

现在,你有这种离奇行为的原因是因为Python(Cpython实现)在实习方面对字符串的处理方式不同。在Python的源代码中有一个intern_string_constants函数,它为字符串提供了要实现的验证,您可以查看更多详细信息。或者查看这篇全面的文章http://guilload.com/python-string-interning/

值得注意的是,Python在intern()模块中有一个sys函数,您可以使用它来手动实习字符串。

In [52]: b = sys.intern('a,,')

In [53]: c = sys.intern('a,,')

In [54]: b is c
Out[54]: True

您可以在需要fasten the dictionary lookups时或在代码中经常使用特定字符串对象时使用此功能。

您不应该与字符串实习混淆的另一点是,当您执行a == b时,您正在创建对同一对象的两个引用,这对于那些关键字具有相同的{ {1}}。

关于标点符号,似乎如果它们是一个字符,如果它们的长度超过一个,它们就会被实现。如果长度超过一个,它们就不会被缓存。正如评论中所提到的,其中一个原因可能是因为关键字和字典键不太可能在其中加上标点符号。

id

但是这些只是你在代码中不能依赖的一些猜测。