Belajar dengan membaca secara berurutan

Constructor __init__ dan Destructor __del__

Panduan praktis untuk __init__ dan __del__ Python. Mencakup atribut wajib, nilai default, dan method cleanup yang dipanggil saat del dan saat program berakhir — semua dengan diagram.

Sebelumnya kamu mendapatkan dasar class dan instance, self, dan bentuk paling sederhana dari __init__. Kali ini kita masuk lebih dalam, menggunakan __init__ untuk memastikan setiap instance lahir dalam kondisi valid. Kita akan membahas argumen wajib yang gagal lantang ketika kamu lupa, argumen default untuk field opsional, dan destructor pasangannya __del__.

Apa yang Terjadi Tanpa __init__

Jika class kamu tidak menginisialisasi atribut dengan benar, kamu bisa berakhir dengan instance yang kehilangan atribut tersebut, dan begitu kamu memanggil method yang menyentuhnya, kamu langsung kena AttributeError.

Pada kode di bawah, User hanya memiliki method set_name — tanpa initializer. Memanggil display() sebelum set_name akan meledak karena self.name belum ada.

class User:
    def set_name(self, name):
        self.name = name

    def display(self):
        print(self.name)

user = User()
user.display()             # AttributeError: tidak ada atribut name
# self.name belum ada sampai kamu memanggil user.set_name("Budi") dulu

Pastikan bahwa memanggil method sebelum menginisialisasi atributnya memicu AttributeError. Jalankan dan saksikan error terjadi.

Python Editor

Jalankan kode untuk melihat output

Gunakan __init__ untuk Memberlakukan Atribut Wajib

__init__ adalah method khusus yang Python panggil otomatis saat instance dibuat. Disebut juga constructor. Nama yang dibungkus double underscore adalah dunder method — konvensi Python untuk method yang dipanggilnya pada momen-momen tertentu.

Dengan mendeklarasikan __init__(self, name, email) dengan parameter wajib, lupa mengoper salah satunya menghentikan program dengan TypeError. Kamu tidak akan pernah berakhir dengan User() yang tidak lengkap, jadi semua kode setelah itu bisa mengandalkan "name dan email pasti diset."

Cara __init__ Terhubung ke Pembuatan Instance
User('Budi', 'budi@x.com')bangun instancekosongpanggil__init__useratribut diset
Memanggil User("Budi", "budi@x.com") membuat Python membangun instance kosong, menjalankan __init__, mengisi atribut, dan mengembalikan instance yang sudah jadi. Lupa argumen dan __init__ sendiri melempar TypeError.
class User:
    def __init__(self, name, email):    # parameter wajib
        print("__init__ dipanggil")
        self.name = name
        self.email = email

    def display(self):
        print(f"{self.name} <{self.email}>")

user = User("Budi", "budi@example.com")  # menetapkan user.name ke "Budi" dan user.email ke "budi@example.com"
# __init__ dipanggil
user.display()
# Budi <budi@example.com>

# Lupa argumen melempar TypeError
# User()  # → TypeError: missing 2 required positional arguments

Tulis __init__ dengan dua parameter wajib dan coba pembuatan, pencetakan, dan apa yang terjadi saat kamu lupa salah satu.

① Definisikan class User:. Di dalam __init__(self, name, email), tulis self.name = name dan self.email = email.

② Definisikan def display(self): yang mencetak f"{self.name} <{self.email}>".

③ Bangun budi = User("Budi", "budi@example.com") dan panggil budi.display(). Pastikan tercetak Budi <budi@example.com>.

④ Lalu coba siti = User("Siti")lupa email — dan pastikan berhenti dengan TypeError (bungkus dalam try / except untuk memeriksa pesan).

(Jika kamu menjalankannya dengan benar, penjelasan akan muncul.)

Python Editor

Jalankan kode untuk melihat output

Argumen Default untuk Field Opsional

__init__ adalah fungsi biasa, jadi kamu bisa memberinya argumen default. Tulis sesuatu seperti age=0, dan pemanggil bisa melewatinya (dan mendapatkan default) atau mengoper nilai. Ini memungkinkan kamu memisahkan desain menjadi "atribut wajib" dan "atribut opsional."

class User:
    def __init__(self, name, email, age=0):   # age opsional
        self.name = name
        self.email = email
        self.age = age

budi = User("Budi", "budi@example.com")            # age dilewati → 0
siti = User("Siti", "siti@example.com", 30)        # age disediakan

print(budi.age)   # 0
print(siti.age)   # 30

Jangan Letakkan list / dict Langsung di Argumen Default

Menulis objek mutable sebagai default — seperti def __init__(self, tags=[]) — terjebak masalah terkenal: semua instance akhirnya berbagi list yang sama. Kita bahas detailnya di Argumen fungsi dan mutability. Itu jebakan yang sama di dalam __init__, jadi solusi standarnya adalah tags=None plus if tags is None: tags = [] di dalam fungsi.

Tulis argumen default sebagai list kosong secara langsung dan saksikan apa yang salah.

① Definisikan class User:. Di dalam __init__(self, name, tags=[]), tulis self.name = name dan self.tags = tags (sengaja meletakkan tags=[] langsung).

② Bangun budi = User("Budi") dan siti = User("Siti").

③ Jalankan budi.tags.append("vip"), lalu print(budi.tags) dan print(siti.tags) — pastikan bahwa siti juga berakhir dengan "vip".

④ Terakhir, print(budi.tags is siti.tags) untuk memastikan mereka berbagi list yang sama.

Python Editor

Jalankan kode untuk melihat output

__del__ — Cleanup Saat Instance Hilang

Dunder method yang berpasangan dengan __init__ adalah __del__ (destructor). Jika __init__ berjalan saat instance dibuat, __del__ berjalan pada saat instance dihancurkan, dipanggil otomatis oleh Python.

Ada dua cara utama penghancuran terjadi:

- Kamu menghapusnya secara eksplisit dengan del nama_variabel

- Memori direklamasi saat program berakhir (instance yang tersisa dihancurkan satu per satu)

Karena kasus kedua, __del__ berjalan saat program keluar bahkan jika kamu tidak memicunya sendiri.

Kapan __init__ dan __del__ Berjalan
panggil User('Budi')__init__menyalauserhidupdel user/ program keluar__del__menyalamemoridilepasbuatsiaphancurkancleanup
Baris atas adalah alur __init__ — berjalan saat instance lahir, dipanggil otomatis oleh Python. Baris bawah adalah alur __del__ — berjalan saat instance mati, baik karena del maupun program berakhir.

__del__ Tidak Berjalan di Eksekusi Browser

Eksekusi sisi-browser di situs ini dibangun di atas MicroPython, yang menurut desainnya tidak memanggil __del__. Contoh kode di bagian ini untuk dibaca dan dipahami perilakunya. Jalankan di CPython di terminal lokal kamu jika kamu ingin benar-benar melihat __del__ menyala.

class User:
    def __init__(self, name):
        print(f"dibuat {name}")
        self.name = name

    def __del__(self):
        print(f"dihancurkan {self.name}")

budi = User("Budi")        # dibuat Budi
siti = User("Siti")        # dibuat Siti

del budi                   # dihancurkan Budi  ← menyala secara eksplisit di sini
print("akan keluar")
# akan keluar
# dihancurkan Siti  ← menyala otomatis saat program keluar

Pola Cleanup Umum — Menghapus Diri Sendiri dari Sebuah List

Penggunaan tipikal __del__ adalah cleanup yang berpasangan dengan pembuatan — seperti "hapus diri saya dari list yang dipegang class." Pada contoh di bawah, class User menambahkan name ke variabel class users saat pembuatan dan menghapusnya saat penghancuran.

class User:
    users = []                         # variabel class: user yang sedang hidup

    def __init__(self, name):
        self.name = name
        User.users.append(name)        # daftarkan saat pembuatan

    def __del__(self):
        User.users.remove(self.name)   # hapus saat penghancuran

budi = User("Budi")
siti = User("Siti")
print(User.users)    # ['Budi', 'Siti']

del budi
print(User.users)    # ['Siti']

Penggunaan Langsung __del__ Jarang dalam Praktik

Kapan __del__ berjalan tergantung pada garbage collector Python, jadi kamu tidak bisa memprediksi waktunya secara andal. Untuk pelepasan deterministik file atau koneksi jaringan, gunakan statement with (context manager) alih-alih __del__.

Kali ini kita membahas penggunaan __init__ secara praktis — memberlakukan atribut wajib dan argumen default — dan menjumpai __del__ pasangannya dengan pola tipikalnya. Kamu sekarang bisa mengontrol "masa hidup sebuah instance dari pembuatan hingga penghancuran" dari sisi Python.

Berikutnya, kita akan menggali kebenaran di balik self.x = ... yang telah kamu tulis tanpa banyak berpikir. Kita akan menyusun dua jenis variabel dalam class — variabel class dan variabel instance — dan menelusuri apa yang sebenarnya dibuat ketika kamu menulis self.x = ..., mengamati referensi dengan id().

QUIZ

Cek Pemahaman

Jawab setiap pertanyaan satu per satu.

Soal 1Jika class C memiliki __init__(self, name), apa yang terjadi saat kamu memanggil C() tanpa argumen?

Soal 2Mana timing yang benar untuk __del__ berjalan?

Soal 3Mengapa menulis def __init__(self, tags=[]) dianggap bermasalah?