【问题标题】:Python intern for non-strings非字符串的 Python 实习生
【发布时间】:2011-08-03 22:44:43
【问题描述】:

为什么 Python 的 intern 仅适用于字符串?应该可以将intern 扩展到可散列和可比较的类,对吧?

【问题讨论】:

  • 您可以为不可变对象创建像 intern 这样的对象缓存。
  • @Peter:你是对的。 intern 的优势在于它的所有代码都是自动生成的,而且作为奖励,它使用快速 C++。
  • @NeilG 我不这么认为。 AFAIK CPython 完全用 C 编写,而不是 C++。

标签: python language-features


【解决方案1】:

intern 的目的是为了能够通过比较它们的内存地址来比较它们;您确保永远不会创建具有相同值的两个对象(当程序请求创建与现有对象具有相同值的第二个对象时,它会接收对预先存在的对象的引用)。这要求你实习的东西是不可变的;如果一个实习对象的值可以改变,那么按地址比较它们是行不通的。

在 Python 中,不可能强制用户定义的类实例的不变性,因此实习它们是不安全的。我怀疑这是实习生不涵盖类实例的主要原因。

其他内置的不可变类型在单个机器级操作中已经具有可比性(int、float 等),或者是可以包含可变值的不可变容器(元组、frozenset)。前者不用实习,后者也不能安全实习。

【讨论】:

  • +1。 “在 Python 中,不可能强制用户定义的类实例的不变性”——多么不幸。
【解决方案2】:

没有技术上的原因,比如说,一个元组不能被实习,尽管我想在现实世界中,与字符串文字相比,它的价值很小,而且它在现实世界中的价值会更低用户定义的类型。让它发挥作用可能不值得付出努力。

【讨论】:

  • 元组的内容可以是可变的。实习元组可能会导致奇怪的行为。例如。 a, b = ([]), ([]); a[0].append('foo') 会产生不同的结果,具体取决于 ab 是否是不同的元组,这取决于元组实习实现。显然 Fortran did something similar 的一些实现。
  • @Peter:实习的整个想法是,只有在没有像您描述的那样副作用的情况下,您才能进行实习。实习元组显然必须检查以确保所有元素都是与已经实习的元组相同的对象,而不仅仅是相等。实际上,它可以尝试首先对元素进行实习(如果数字类型也可以进行实习,这将更加有用)。在您的示例中,如果元组不包含相同的列表,则它们根本无法共享引用。没有技术原因不能修改 Python 来完成这一切。
【解决方案3】:

仅支持字符串,因为实习依赖于基于指针的object identity test。可以比较其他类型的类的哈希,但对象本身永远不会匹配身份测试。这是真的,因为即使它们可能相同,它们也不是相同的对象。

Reference

【讨论】:

  • 据我了解,基于指针的对象身份测试是您通过实习获得的好处,而不是实习所需要的。如果您要求实习对象,那么您本质上是在考虑具有相同值的任何两个对象具有相同的身份(我相信这是 Neil G 所说的“可散列和可比较”时的意思)。这反过来又要求它们是不可变的,这不是 Python 中类实例的强制属性。我猜这是它不受支持的主要原因。
  • @Ben:这是对我的问题的一个很好的解释。另外,你的最后一点可能是这个问题的答案。随意添加答案。
猜你喜欢
  • 2013-03-10
  • 2013-07-14
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
相关资源
最近更新 更多