Tiga object Buku pada Chapter *Constructor dan __init__ lahir dari class yang sama, tetapi masing-masing menyimpan judul dan penulisnya sendiri. Data per-object inilah yang disebut instance attribute — konsep yang tampak sepele tetapi menyimpan beberapa detail penting: di mana data itu sebenarnya disimpan, bagaimana menambah attribute setelah object dibuat, dan mengapa dua object dengan isi sama tetap bukan object yang sama. Chapter ini membedah ketiganya langsung dari dalam mesin Python.
Data Milik Setiap Object #
Mulai dari pertanyaan paling mendasar: apakah mengubah attribute satu object ikut mengubah object lain? Mari kita uji dengan dua instance berisi judul yang sama:
class Buku:
def __init__(self, judul):
self.judul = judul
salinan_a = Buku("Laskar Pelangi")
salinan_b = Buku("Laskar Pelangi")
salinan_a.judul = "Laskar Pelangi (Edisi Revisi)"
print(salinan_a.judul)
print(salinan_b.judul)Output yang Dihasilkan:
Laskar Pelangi (Edisi Revisi)
Laskar PelangiAssignment salinan_a.judul = ... hanya menyentuh object salinan_a. Meskipun kedua object dibuat dengan nilai awal yang sama, keduanya tetap dua object terpisah — sama seperti dua rumah kembar yang pintunya bisa dikunci berbeda. Setiap pemanggilan Buku(...) menjalankan __init__ dengan self yang berbeda, dan self.judul = judul memasang attribute pada object masing-masing.
Melihat Isi Instance dengan vars() dan dict #
Di balik layar, setiap object menyimpan instance attribute dalam sebuah dictionary internal. Fungsi vars() dan attribute __dict__ membuka kamus tersebut langsung:
class Buku:
def __init__(self, judul, penulis):
self.judul = judul
self.penulis = penulis
buku1 = Buku("Laskar Pelangi", "Andrea Hirata")
buku2 = Buku("Bumi Manusia", "Pramoedya A. Toer")
print(vars(buku1))
print(vars(buku2))
print(buku1.__dict__)Output yang Dihasilkan:
{'judul': 'Laskar Pelangi', 'penulis': 'Andrea Hirata'}
{'judul': 'Bumi Manusia', 'penulis': 'Pramoedya A. Toer'}
{'judul': 'Laskar Pelangi', 'penulis': 'Andrea Hirata'}Mari kita telaah hasilnya:
vars(buku1)danbuku1.__dict__menampilkan dictionary yang sama persis —vars()hanyalah pintasan menuju__dict__.- Urutan key mengikuti urutan pemasangan attribute:
judullebih dulu karena barisself.judul = judulditulis lebih dulu di__init__. Dictionary Python menjaga urutan penyisipan seperti dibahas pada Chapter Dictionary. buku2punya kamusnya sendiri dengan isi berbeda — inilah bukti visual bahwa instance attribute tidak pernah tercampur antar object.
Kamus ini adalah alat debugging yang jujur: ketika sebuah object berperilaku aneh, mencetak vars(objek) langsung memperlihatkan data apa saja yang sebenarnya menempel.
Menambah Attribute Setelah Object Dibuat #
Python tidak mengunci bentuk object. Attribute baru bisa dipasang kapan saja, bahkan di luar __init__:
class Buku:
def __init__(self, judul, penulis):
self.judul = judul
self.penulis = penulis
buku1 = Buku("Laskar Pelangi", "Andrea Hirata")
buku2 = Buku("Bumi Manusia", "Pramoedya A. Toer")
buku1.rating = 5
buku1.sudah_dibaca = True
print(vars(buku1))
print(vars(buku2))Output yang Dihasilkan:
{'judul': 'Laskar Pelangi', 'penulis': 'Andrea Hirata', 'rating': 5, 'sudah_dibaca': True}
{'judul': 'Bumi Manusia', 'penulis': 'Pramoedya A. Toer'}Attribute rating dan sudah_dibaca hanya menempel pada buku1; kamus buku2 tidak berubah. Membaca attribute yang tidak ada tentu saja gagal:
class Buku:
def __init__(self, judul, penulis):
self.judul = judul
self.penulis = penulis
buku2 = Buku("Bumi Manusia", "Pramoedya A. Toer")
print(buku2.rating)Output yang Dihasilkan:
Traceback (most recent call last):
File "03d-error-rating.py", line 8, in <module>
print(buku2.rating)
^^^^^^^^^^^^
AttributeError: 'Buku' object has no attribute 'rating'Interpreter mencari rating di kamus buku2, tidak menemukannya, lalu memunculkan AttributeError. (Nama file pada baris File "..." bisa berbeda di komputer lain — bentuk pesannya tetap sama.)
Urutan Pencarian Attribute #
Ada satu pertanyaan yang belum terjawab: apa yang terjadi jika class juga menyimpan attribute dengan nama yang sama? Python memakai urutan pencarian dua tingkat — instance dulu, baru class:
class Buku:
jenis_media = "cetak"
def __init__(self, judul):
self.judul = judul
buku1 = Buku("Laskar Pelangi")
buku2 = Buku("Bumi Manusia")
print(buku1.jenis_media)
buku1.jenis_media = "digital"
print(buku1.jenis_media)
print(buku2.jenis_media)
print(Buku.jenis_media)Output yang Dihasilkan:
cetak
digital
cetak
cetakMari kita telaah baris-baris kode di atas:
- Baris 2 (
jenis_media = "cetak"): assignment di body class (di luar method) membuat class attribute — konsep penuhnya di Chapter Class Attributes. - Baris 10 (
print(buku1.jenis_media)): kamusbuku1tidak memilikijenis_media, jadi interpreter melanjutkan pencarian ke class dan menemukan"cetak". - Baris 12 (
buku1.jenis_media = "digital"): assignment pada instance membuat attribute di kamusbuku1sendiri. Nilai di class tidak tersentuh. - Baris 14-16: sejak saat itu
buku1membaca nilai miliknya sendiri (digital), sedangkanbuku2masih jatuh ke class, danBuku.jenis_mediatetap"cetak".
Mekanisme dua tingkat ini menjelaskan mengapa reading lewat instance bisa “melihat” data class, tetapi writing lewat instance hanya mengubah instance. Aturan ini akan terus kita pakai di sepanjang Section — terutama ketika class attribute menyimpan object mutable pada Chapter Class Attributes.