Duplikat lain menanyakan mengapa dua string yang sama umumnya tidak identik, yang sebenarnya tidak dijawab di sini:
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
Jadi, mengapa mereka tidak memiliki string yang sama? Terutama mengingat ini:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
Mari kita tunda bagian kedua sebentar. Bagaimana yang pertama bisa benar?
Penerjemah harus memiliki "tabel interning", tabel yang memetakan nilai string ke objek string, jadi setiap kali Anda mencoba membuat string baru dengan konten 'abc'
, Anda mendapatkan objek yang sama. Wikipedia memiliki diskusi yang lebih rinci tentang cara kerja magang.
Dan Python memiliki tabel interning string; Anda bisa memasukkan string internal secara manual dengan sys.intern
metode ini.
Faktanya, Python diizinkan untuk secara otomatis menyimpan tipe yang tidak dapat diubah, tetapi tidak diharuskan untuk melakukannya. Implementasi yang berbeda akan memiliki nilai yang berbeda pula.
CPython (implementasi yang Anda gunakan jika Anda tidak tahu implementasi mana yang Anda gunakan) auto-interns bilangan bulat kecil dan beberapa singlet khusus seperti False
, tetapi bukan string (atau bilangan bulat besar, atau tupel kecil, atau apa pun). Anda dapat melihat ini dengan mudah:
>>> 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
Oke, tapi kenapa z
dan w
identik?
Itu bukan interpreter yang secara otomatis melakukan intern, itulah nilai lipat kompilator.
Jika waktu kompilasi yang sama string yang muncul dua kali dalam modul yang sama (apa sebenarnya berarti ini sulit untuk menentukan-itu bukan hal yang sama sebagai literal string yang, karena r'abc'
, 'abc'
dan 'a' 'b' 'c'
semua literal berbeda tetapi sama string tetapi mudah dimengerti secara intuitif), kompilator hanya akan membuat satu turunan dari string, dengan dua referensi.
Faktanya, kompilator dapat melangkah lebih jauh: 'ab' + 'c'
dapat dikonversi 'abc'
oleh pengoptimal, dalam hal ini dapat dilipat bersama dengan 'abc'
konstanta dalam modul yang sama.
Sekali lagi, ini adalah sesuatu yang diperbolehkan Python tetapi tidak wajib dilakukan. Tetapi dalam kasus ini, CPython selalu melipat string kecil (dan juga, misalnya, tupel kecil). (Meskipun compiler pernyataan-demi-pernyataan interpreter interaktif tidak menjalankan pengoptimalan yang sama seperti compiler module-at-a-time, jadi Anda tidak akan melihat hasil yang persis sama secara interaktif.)
Jadi, apa yang harus Anda lakukan sebagai programmer?
Yah… tidak ada. Anda hampir tidak pernah memiliki alasan untuk peduli jika dua nilai yang tidak dapat diubah itu identik. Jika Anda ingin tahu kapan Anda bisa menggunakan a is b
alih-alih a == b
, Anda menanyakan pertanyaan yang salah. Selalu gunakan a == b
kecuali dalam dua kasus:
- Untuk perbandingan yang lebih mudah dibaca dengan nilai tunggal seperti
x is None
.
- Untuk nilai yang bisa berubah, saat Anda perlu mengetahui apakah mutasi
x
akan memengaruhi y
.