Banyak perilaku Python yang tampak aneh bagi pemula, misalnya dua variabel yang berubah bersamaan padahal hanya satu yang disentuh, ternyata berasal dari satu akar: variabel di Python bukanlah kotak yang menyimpan nilai, melainkan nama yang menunjuk ke sebuah object di memori. Pada Chapter ini kita akan membangun model mental tersebut, memahami apa yang sebenarnya terjadi pada assignment a = b, dan membedakan operator is dari operator ==.

Names Terikat ke Object #

Dalam model Python, object adalah satuan data di memori yang memiliki tiga identitas utama: nilai, tipe, dan alamat identitas yang unik. Name (nama variabel) hanyalah pengenal yang diikatkan ke object tersebut, sering disebut reference. Satu object boleh ditunjuk oleh banyak nama sekaligus; satu nama juga boleh dipindahkan dari satu object ke object lain kapan saja lewat assignment.

Setiap object memiliki identitas yang bisa diperiksa dengan fungsi bawaan id(). Nilai yang dikembalikan id() berbeda-beda pada setiap eksekusi program, sehingga kita tidak akan mencetak nilainya secara langsung; untuk membandingkan identitas dua object, gunakan operator is seperti yang akan kita praktikkan di bagian akhir Chapter ini.

Karena name hanyalah penunjuk, assignment tidak pernah menyalin isi object. Perhatikan perbedaan dua pernyataan berikut:

  • b = a mengarahkan nama b ke object yang sedang ditunjuk a — keduanya kini berbagi satu object.
  • a = 200 mengikatkan nama a ke object baru — object lama yang ditunjuk nama lain tidak tersentuh.

Pemisahan antara “mengubah object” dan “memindahkan nama” ini adalah kunci memahami sisa Chapter.

Assignment a = b Membagi Object yang Sama #

Mari kita lihat konsekuensi berbagi object ketika object tersebut bisa diubah isinya (seperti list):

python
daftar_a = [1, 2, 3]
daftar_b = daftar_a
daftar_a.append(4)
print("daftar_a:", daftar_a)
print("daftar_b:", daftar_b)

Output yang Dihasilkan:

text
daftar_a: [1, 2, 3, 4]
daftar_b: [1, 2, 3, 4]

Mari kita telaah baris-baris kode di atas:

  1. Baris 1 (daftar_a = [1, 2, 3]): interpreter membuat object list berisi tiga angka, lalu mengikatkan nama daftar_a ke object tersebut.
  2. Baris 2 (daftar_b = daftar_a): interpreter tidak menyalin isi list; interpreter hanya mengikatkan daftar_b ke object yang sama dengan yang ditunjuk daftar_a.
  3. Baris 3 (daftar_a.append(4)): method append() menambahkan 4 ke dalam object list itu — object yang sama yang juga ditunjuk daftar_b.
  4. Baris 4-5 (print(...)): kedua nama mencetak object yang sama, sehingga keduanya terlihat berubah bersamaan.

Bandingkan dengan kasus memindahkan nama ke object baru:

python
a = 100
b = a
a = 200
print("a =", a)
print("b =", b)

Output yang Dihasilkan:

text
a = 200
b = 100

Pada baris a = 200, nama a diikat ulang ke object 200 yang baru, sementara nama b tetap menunjuk object 100 yang lama. Tidak ada perubahan pada object mana pun di sini; yang berubah hanyalah arah penunjukan nama a.

Operator is versus == #

Kedua operator ini sering tertukar padahal tugasnya berbeda:

  • Operator == membandingkan nilai: apakah isi kedua object dianggap sama?
  • Operator is membandingkan identitas: apakah kedua nama menunjuk ke satu object yang sama persis?
python
x = [1, 2]
y = [1, 2]
z = x
print(x == y)
print(x is y)
print(z is x)

Output yang Dihasilkan:

text
True
False
True

Mari kita bedah hasilnya:

  1. Baris 4 (print(x == y)): menghasilkan True karena kedua list berisi nilai yang sama, yakni 1 dan 2.
  2. Baris 5 (print(x is y)): menghasilkan False karena x dan y adalah dua object terpisah yang kebetulan berisi sama.
  3. Baris 6 (print(z is x)): menghasilkan True karena z = x mengarahkan kedua nama ke object yang identik.

Sebagai pedoman praktis, gunakan == untuk membandingkan nilai sehari-hari, dan gunakan is khusus untuk memeriksa identitas terhadap object tunggal seperti None — pola yang akan kita pakai pada Chapter None dan NoneType.