Python实习生字符串吗?

时间:2013-07-16 14:49:09

标签: python memoization string-interning

在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个单独的字符串?

4 个答案:

答案 0 :(得分:13)

这称为实习,是的,Python确实在某种程度上这样做,对于作为字符串文字创建的较短字符串。有关讨论,请参阅About the changing id of a Python immutable string

实习依赖于运行时,没有标准。如果要创建相同的字符串,实习总是在内存使用和检查成本之间进行权衡。如果您愿意,可以使用built-in intern() function来强制解决问题,实际Python中的部分文档会自动为您执行此操作:

  

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

请注意,Python 3将intern()函数移动到sys module

答案 1 :(得分:3)

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

class example():

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

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

答案 2 :(得分:1)

  • 所有长度为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中的字符串实习。本文中明确定义了一些例外。

答案 3 :(得分:0)

某些字符串已在python中进行了检查。在编译python代码时,标识符会被嵌入,例如变量名,函数名,类名。

满足以下划线或字符串开头并且仅包含下划线,字符串和数字的标识符规则的字符串:

a="hello"
b="hello"

由于字符串是不可变的,因此python在此处共享内存引用,并且

a is b ===> True

但是如果我们有

a="hello world"
b="hello world"

由于“ hello world”不符合标识符规则,因此a和b不会被拘禁。

a is b  ===> False

您可以使用sys.intern()进行实习。如果您的代码中有很多重复字符串,请使用此方法。

a=sys.intern("hello world")
b=sys.intern("hello world")

现在 a是b ===>是