Meskipun pertanyaan ini tidak memiliki kegunaan nyata dalam praktiknya, saya ingin tahu bagaimana Python melakukan interning string. Saya telah memperhatikan yang berikut ini.
>>> "string" is "string"
True
Ini seperti yang saya harapkan.
Anda juga bisa melakukan ini.
>>> "strin"+"g" is "string"
True
Dan itu sangat pintar!
Tapi Anda tidak bisa melakukan ini.
>>> s1 = "strin"
>>> s2 = "string"
>>> s1+"g" is s2
False
Mengapa Python tidak mengevaluasi s1+"g"
, dan menyadari bahwa itu sama s2
dan mengarahkannya ke alamat yang sama? Apa yang sebenarnya terjadi di blok terakhir untuk mendapatkannya kembali False
?
"string1" + "s2"
,10 + 3*20
, dll) pada waktu kompilasi, tetapi batas dihasilkan urutan hanya 20 elemen (untuk mencegah[None] * 10**1000
dari terlalu memperluas bytecode Anda). Pengoptimalan inilah yang runtuh"strin" + "g"
menjadi"string"
; hasilnya lebih pendek dari 20 karakter.intern()
fungsi.intern
fungsi di Python 3 - itu dipindahkan ke sys.internKasus 1
>>> x = "123" >>> y = "123" >>> x == y True >>> x is y True >>> id(x) 50986112 >>> id(y) 50986112
Kasus 2
>>> x = "12" >>> y = "123" >>> x = x + "3" >>> x is y False >>> x == y True
Sekarang, pertanyaan Anda adalah mengapa id sama dalam kasus 1 dan bukan dalam kasus 2.
Dalam kasus 1, Anda telah menetapkan literal string
"123"
kex
dany
.Karena string tidak dapat diubah, masuk akal bagi penerjemah untuk menyimpan string literal hanya sekali dan mengarahkan semua variabel ke objek yang sama.
Karenanya Anda melihat id sebagai identik.
Dalam kasus 2, Anda memodifikasi
x
menggunakan penggabungan. Keduanyax
dany
memiliki nilai yang sama, tetapi tidak memiliki identitas yang sama.Keduanya menunjuk ke objek yang berbeda dalam memori. Oleh karena itu mereka berbeda
id
danis
operator kembaliFalse
sumber
id(x) != id(x)
misalnya, karena string dipindahkan dalam proses evaluasi.x = "12" + "3"
ke dalamx = "123"
(penggabungan dua string literal dalam ekspresi tunggal) sehingga tugas benar-benar melakukan pencarian dan menemukan string "internal" yang sama seperti untuky = "123"
.