【问题标题】:What are the rules for cpython's string interning?cpython的字符串实习规则是什么?
【发布时间】:2016-06-18 18:17:05
【问题描述】:

在 python 3.5 中,是否可以预测我们何时会得到一个实习字符串或何时会得到一个副本?在阅读了有关此问题的一些 Stack Overflow 答案后,我发现 this one 最有帮助,但仍然不全面。比我看的Python docs,但是默认不保证实习

通常,Python程序中使用的名称是自动interned,用于保存模块、类或实例属性的字典有interned键。

所以,我的问题是关于内部 intern() 条件,即决策(是否实习字符串文字):为什么同一段代码在一个系统上工作而不是在另一个系统上工作,以及作者制定了哪些规则mentioned topic 上的答案意思是说

发生这种情况的规则非常复杂

【问题讨论】:

  • @erip 我相信 OP 已经意识到了这一点。通过样板后,这个问题似乎是在询问实习规则。
  • 如果你真的想知道实现上的差异,指定两个系统上安装的 Python 版本可能是有意义的。
  • @wim 我不想忘记,我想学习和理解。
  • @wim 我很乐意,但我对 Python 的经验不是很高,所以欢迎你自己编辑你看到的问题
  • 唯一的规则是intern的返回值是interned。其他一切都是实现细节的泥潭,不一致,因为保持一致毫无意义。

标签: string cpython string-interning


【解决方案1】:

你认为有规则

interning 的唯一规则是intern 的返回值是interned。其他一切都取决于决定某段代码应该或不应该实习的人的心血来潮。例如,"left"PyCodeNew 实习:

/* Intern selected string constants */
for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) {
    PyObject *v = PyTuple_GetItem(consts, i);
    if (!all_name_chars(v))
        continue;
    PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
}

这里的“规则”是,如果 Python 代码对象的 co_consts 中的字符串对象纯粹由 Python 标识符中合法的 ASCII 字符组成,则该字符串对象将被拦截。 "left" 被实习,但 "as,df" 不会被实习,即使标识符不能以数字开头,"1234" 也会被实习。虽然标识符可以包含非 ASCII 字符,但此检查仍会拒绝此类字符。 实际标识符永远不会通过此代码;他们无条件地被拘留了几行,ASCII 与否。此代码可能会更改,还有很多其他代码可以做实习或类似实习的事情。

向我们询问字符串实习的“规则”就像向气象学家询问婚礼是否下雨的规则是什么。我们可以告诉你很多关于它的工作原理,但它对你没有多大用处,而且你总会得到惊喜。

【讨论】:

    【解决方案2】:

    根据我从您链接的帖子中了解到的情况:

    当你使用if a == b时,你正在检查a的值是否是b的值,而当你使用if a is b时,你正在检查ab是否相同对象(或共享内存中的同一位置)。

    现在 python 实习生字符串(由 "blabla" 定义)。 所以:

    >>> a = "abcdef"
    >>> a is "abcdef"
    True
    

    但是当你这样做时:

    >>> a = "".join([chr(i) for i in range(ord('a'), ord('g'))])
    >>> a
    'abcdef'
    >>> a is "abcdef"
    False
    

    C 编程语言中,使用带有"" 的字符串将使其成为const char *。我认为这就是这里正在发生的事情。

    【讨论】:

      猜你喜欢
      • 2012-05-21
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 2013-01-06
      • 2019-05-29
      • 2022-04-19
      • 2013-07-14
      相关资源
      最近更新 更多