python如何做魔术?

时间:2014-09-05 04:39:02

标签: python string python-internals

今天我对一个字符串比较感到困惑:似乎python重用了字符串(这是一个明智的做法,因为它们是不可变的)。为了检查这个事实,我做了以下事情:

>>> a = 'xxx'
>>> b = 'xxx'
>>> a == b
True
>>> a is b
True
>>> id(a)
140141339783816
>>> id(b)
140141339783816
>>> c = 'x' * 3
>>> id(c)
140141339783816
>>> d = ''.join(['x', 'x', 'x'])
>>> id(d)
140141339704576

这有点令人惊讶。一些问题:

  • python在定义新字符串时是否检查其字符串表的全部内容?
  • 字符串大小是否有限制?
  • 这种机制如何工作(比较字符串的哈希值?)
  • 它似乎并不用于所有类型的生成字符串。这里的规则是什么?

1 个答案:

答案 0 :(得分:0)

由于这个问题有一些赞成(尽管有些重复),我将在这里回答我原来的问题(感谢上面的评论):

  1. 是的,python检查内部表的整个内容:但仅限于某些字符串,主要是那些也可以用作标识符的字符串。这个想法是python解释器(编译器?)用于标识符处理的加速技巧对于通用字符串处理也很有用。该过程称为 interning
  2. 据我所知,字符串大小没有限制,但是还有其他规则可以重用字符串(主要是:它们必须看起来像python标识符)
  3. 是的,该表是一个普通的python dict,字符串有一个查找的哈希值。
  4. 它仅用于字符串文字和常量表达式。基本上对于python解释器在编译阶段可以推断的所有事情。
  5. 为了澄清最后一点,以下片段在所有情况下都会对字符串'xxx'进行评估,但在实习时会对它们进行不同的处理。

    这是一个常量表达式:

    'x' * 3
    

    但这不是:

    a = 'x'
    a * 3   # this is no constant expression, so no interning can be applied.
    

    这不是表达方式:

    ''.join(['x', 'x', 'x']) # this is no expression (a function is called)