问题 Python实习生字符串吗?


在Java中,显式声明的字符串由JVM实现,因此相同String的后续声明会产生两个指向同一String实例的指针,而不是两个单独的(但相同的)字符串。

例如:

public String baz() {
    String a = "astring";
    return a;
}

public String bar() {
    String b = "astring"
    return b;
}

public void main() {
    String a = baz()
    String b = bar()
    assert(a == b) // passes
}

我的问题是,CPython(或任何其他Python运行时)对字符串执行相同的操作吗?例如,如果我有一些课程:

class example():
    def __init__():
        self._inst = 'instance' 

并创建这个类的10个实例,它们中的每一个都有一个实例变量引用内存中的相同字符串,或者我最终会得到10个单独的字符串?


11840
2017-07-16 14:49


起源

这被称为实习,是的,Python确实在某种程度上这样做,对于作为字符串文字创建的较短字符串。看到 Python字符串实习 - Martijn Pieters♦
可能重复 Python'=='vs'是'比较字符串','有时'失败,为什么? - OptimusCrime
@MartijnPieters - 谢谢,但“短”字符串有多短?这是运行时依赖的,还是有标准的呢? - csvan
@chrsva:它依赖于运行时,没有标准。如果要创建相同的字符串,实习总是在内存使用和检查成本之间进行权衡。有一个 内建的 intern() 功能 如果你这么倾向强迫这个问题。 - Martijn Pieters♦
@MartijnPieters - 我明白了,谢谢!如果你愿意,你可以提出你的答案,我会马上接受。 - csvan


答案:


这称为实习,是的,Python确实在某种程度上这样做,对于作为字符串文字创建的较短字符串。看到 关于Python不可变字符串的更改ID 进行一些讨论。

实习依赖于运行时,没有标准。如果要创建相同的字符串,实习总是在内存使用和检查成本之间进行权衡。有一个 内置的intern()函数 如果你是如此倾向于强制问题,哪些文件 一些 实习Python的功能会自动为您完成:

通常,Python程序中使用的名称会自动实现,而用于保存模块,类或实例属性的字典具有实习键。

请注意,Python 3移动了 intern() 功能 sys 模


12
2017-07-16 15:04



请注意 intern 内置似乎已经在Python 3中删除了。我不想现在正确地挖掘哪个版本。 - zwol
@zwol:3.0。我会看看我是否能找到动机,可能是在PEP的某个地方。 - Martijn Pieters♦
@zwol:它被移到了 sys 模块。 - Martijn Pieters♦


一个相当简单的方法是使用 id()。但是,正如@MartijnPieters所提到的,这取决于运行时。

class example():

    def __init__(self):
        self._inst = 'instance'

for i in xrange(10):
    print id(example()._inst)

3
2017-07-16 15:05





  • 所有长度为0和长度为1的字符串都被实现。
  • 字符串在编译时被实习('wtf'将被实习,但''.join(['w','t','f']将不会被实习)
  • 不包含ASCII字母,数字或下划线的字符串。这解释了为什么'wtf!'由于没有被拘禁!

https://www.codementor.io/satwikkansal/do-you-really-think-you-know-strings-in-python-fnxh8mtha

上面的文章解释了python中的字符串实习。本文中明确定义了一些例外情况。


1
2017-07-02 14:30