Outra duplicata estava perguntando por que duas strings iguais geralmente não são idênticas, o que realmente não foi respondido aqui:
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
Então, por que eles não são a mesma string? Especialmente por causa disso:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
Vamos adiar a segunda parte um pouco. Como o primeiro pode ser verdade?
O intérprete teria que ter uma "tabela interna", uma tabela que mapeia valores de string para objetos de string, então toda vez que você tenta criar uma nova string com o conteúdo 'abc'
, você obtém o mesmo objeto. A Wikipedia tem uma discussão mais detalhada sobre como funciona o estágio.
E o Python tem uma mesa de internação de strings; você pode internar strings manualmente com o sys.intern
método.
Na verdade, o Python tem permissão para internar automaticamente qualquer tipo imutável, mas não é obrigado a fazer isso. Implementações diferentes irão internalizar valores diferentes.
CPython (a implementação que você está usando se não sabe qual implementação está usando) internaliza automaticamente pequenos inteiros e alguns singletons especiais como False
, mas não strings (ou inteiros grandes, ou tuplas pequenas, ou qualquer outra coisa). Você pode ver isso facilmente:
>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False
OK, mas por que eram z
e w
idênticos?
Esse não é o intérprete internando automaticamente, mas sim os valores de dobramento do compilador.
Se a mesma seqüência de tempo de compilação aparece duas vezes no mesmo módulo (o que exatamente isto significa é difícil de definir-não é a mesma coisa que um literal de cadeia, porque r'abc'
, 'abc'
e 'a' 'b' 'c'
são todos literais diferentes, mas a mesma cadeia, mas fácil de entender intuitivamente), o compilador criará apenas uma instância da string, com duas referências.
Na verdade, o compilador pode ir ainda mais longe: 'ab' + 'c'
pode ser convertido para 'abc'
pelo otimizador, caso em que pode ser dobrado junto com uma 'abc'
constante no mesmo módulo.
Novamente, isso é algo que o Python é permitido, mas não obrigatório. Mas, neste caso, CPython sempre dobra pequenas strings (e também, por exemplo, pequenas tuplas). (Embora o compilador instrução por instrução do interpretador interativo não execute a mesma otimização que o compilador módulo por vez, então você não verá exatamente os mesmos resultados interativamente.)
Então, o que você deve fazer a respeito disso como programador?
Bem ... nada. Você quase nunca tem motivos para se importar se dois valores imutáveis são idênticos. Se você quiser saber quando pode usar em a is b
vez de a == b
, você está fazendo a pergunta errada. Use sempre, a == b
exceto em dois casos:
- Para obter comparações mais legíveis com os valores singleton, como
x is None
.
- Para valores mutáveis, quando você precisa saber se a mutação
x
afetará o y
.