Atribut Python: Memahami Cara Kerjanya 🐍

Atribut adalah fondasi model objek Python, tetapi kebanyakan pemula (dan bahkan banyak level menengah) menggunakannya secara intuitif, tanpa memahami apa yang terjadi "di balik kap". Akibatnya — perilaku kode yang tidak terduga, pemborosan memori, dan API spageti.

Mari kita pahami nuansanya 👇

1️⃣ Urutan Pencarian (MRO)
Python hidup dengan prinsip: pertama objek, lalu kelas.

Saat Anda mengakses obj.attr, interpreter pertama-tama mencari di obj.__dict__. Jika tidak ditemukan, ia pergi ke Class.__dict__.
Jika Anda secara tidak sengaja menulis sesuatu ke obj.attr, Anda membuat atribut instance yang akan menyembunyikan atribut kelas.

class Hero:
weapon = "Sword"

h = Hero()
h.weapon = "Gun" # Sekarang h punya senjata sendiri, kelas masih dengan pedang

Ini bukan bug, ini fitur, tetapi kendalikan. Jika ingin mengubah atribut untuk semua — akses kelas.

2️⃣ __dict__ vs __slots__
Secara default, setiap objek memiliki __dict__ — tabel hash (dictionary) tempat atribut disimpan. Ini fleksibel, tetapi boros memori.

Jika Anda membuat jutaan objek dengan tipe yang sama, gunakan __slots__.
🔵Apa yang diberikannya: Kita mencegah pembuatan __dict__ untuk instance, secara kaku menetapkan kumpulan atribut dalam memori (seperti array).
🔵Keuntungan: Mengurangi konsumsi memori 25-30% dan akses sedikit lebih cepat.
🔵Harga: Anda kehilangan kemampuan dinamis untuk menambahkan atribut baru dengan cepat.

3️⃣ Ilusi Enkapsulasi
Di Python tidak ada field "private". Sama sekali.
Konstruksi seperti __attribute bukanlah perlindungan data, melainkan name mangling (pengacauan nama). Python hanya mengganti nama variabel menjadi _ClassName__attribute agar tidak tertimpa secara tidak sengaja di kelas turunan.
Jika Anda menulis __ dengan harapan tidak ada yang bisa mengakses data Anda, maka siapa pun yang bisa menggunakan dir() akan melihat semuanya. Menulis _private (satu garis bawah) berarti "jangan sentuh, ini API internal". Ini masalah budaya, bukan kompiler.

Ingin menyembunyikan data? Gunakan satu garis bawah _ hanya sebagai sinyal ke rekan kerja: "Jangan sentuh ini, ini urusan internal".

4️⃣ @property: Getter yang Etis
Jangan pernah membuat getter gaya Java di Python (get_value(), set_value()). Jika Anda memerlukan logika saat mengakses atribut — gunakan @property.
@property memungkinkan Anda mengubah metode menjadi atribut. Anda mempertahankan API yang bersih (akses melalui titik), tetapi di balik kap Anda dapat memvalidasi data, mencatat akses, atau menghitung nilai dengan cepat.
class DataStorage:
def __init__(self, value):
self._value = value

@property
def value(self):
return self._value

@value.setter
def value(self, new_val):
if not isinstance(new_val, int):
raise ValueError("Hanya int, sayang") self._value = new_val


Dengan begitu Anda mempertahankan antarmuka yang bersih: obj.value = 10 terlihat sesederhana bekerja dengan field biasa, tetapi Anda mengontrol apa yang ditulis ke dalamnya.

Bagian "ajaib" lain di Python apa yang membuat Anda bertanya-tanya? Tulis di komentar, kita bahas. 👇

#anatomi_python