2013-07-16 2 views
10

В Java явно объявлены строки, интернированные JVM, так что последующие объявления одной и той же строки приводят к двум указателям к одному экземпляру String, а не к двум отдельным (но идентичным) строкам.Использует ли строки Python?

Например:

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 отдельными строками ?

+3

Это называется интернированием, и да, Python делает это в некоторой степени, для более коротких строк, созданных как строковые литералы. См. [Интерпретация строки Python] (http://stackoverflow.com/q/15541404) –

+0

Возможный дубликат [Python '==' vs 'is' Сравнение строк, 'иногда' не удается, почему?] (Http: // stackoverflow.com/questions/1504717/python-vs-is-comparing-strings-is-fails-sometimes-why) – OptimusCrime

+0

@MartijnPieters - спасибо, но насколько короткими являются «короткие» строки? Является ли это зависимым от времени выполнения, или есть стандарт для этого? – csvan

ответ

11

Это называется интернированием, и да, Python делает это в некоторой степени, для более коротких строк, созданных как строковые литералы. См. About the changing id of a Python immutable string для обсуждения.

Interning зависит от времени выполнения, для него нет стандарта. Interning всегда является компромиссом между использованием памяти и стоимостью проверки, если вы создаете одну и ту же строку. Существует built-in intern() function форсировать, если вы так склонны, какие документы некоторые из интернирования Python делает для вас автоматически:

Обычно, имена, используемые в программах Python автоматически интернированы и используются словари для хранения атрибутов модуля, класса или экземпляра есть интернированные ключи.

Обратите внимание, что Python 3 переместил функцию intern() на sys module.

+0

Обратите внимание, что встроенный встроенный модуль, как представляется, был удален в Python 3. Я не чувствую как выкапывать именно ту версию прямо сейчас. – zwol

+0

@zwol: 3.0. Я посмотрю, смогу ли я найти мотивацию, возможно, в PEP. –

+0

@zwol: он был перемещен в модуль 'sys'. –

3

Достаточно простой способ рассказать, используя id(). Однако, как отмечает @MartijnPieters, это зависит от времени выполнения.

class example(): 

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

for i in xrange(10): 
    print id(example()._inst) 
Смежные вопросы