pythonoopclassMenengah4 mnt baca

OOP Dasar di Python

class, __init__, method: cukup paham konsepnya karena objek pandas bekerja dengan cara ini.

OOP: cetakan kue dan kuenya

Analogi singkat: class adalah cetakan kue, objek adalah kue yang dicetak. Dari satu cetakan (class Produk) kamu bisa membuat banyak kue (objek kopi, teh) yang bentuknya sama tapi isinya beda-beda. Kenapa analyst perlu tahu ini? Karena kamu memakai objek setiap hari tanpa sadar: DataFrame itu objek, Series itu objek. Memahami class bikin dokumentasi pandas jauh lebih masuk akal: kamu langsung paham kenapa menulis df.head() bukan head(df).

Contoh 1: class pertamamu

python
class Produk:
    def __init__(self, nama, harga):
        self.nama = nama
        self.harga = harga

    def info(self):
        return f"{self.nama}: Rp{self.harga:,}"

kopi = Produk("Kopi Tubruk", 15000)
teh = Produk("Teh Manis", 8000)
print(kopi.info())  # Kopi Tubruk: Rp15,000
print(teh.info())   # Teh Manis: Rp8,000

Tiga istilah kunci. __init__ adalah constructor yang jalan otomatis saat objek dibuat (di sinilah data "dituang ke cetakan"). self merujuk ke objek itu sendiri, tempat menyimpan data miliknya. Method adalah fungsi yang menempel di class dan selalu menerima self sebagai parameter pertama: saat kamu memanggil kopi.info(), Python otomatis mengisi self dengan kopi.

Catatan teknis: Inilah kenapa kamu menulis df.head() bukan head(df). df adalah objek DataFrame, head() adalah method miliknya. Setelah paham pola ini, seluruh API pandas terasa konsisten: objek menyimpan data, method melakukan sesuatu dengan data itu.

Contoh 2 (realistis): class Transaksi untuk rekap penjualan

Class bersinar saat data punya perilaku: bukan cuma menyimpan, tapi juga bisa menghitung dirinya sendiri.

python
class Transaksi:
    def __init__(self, produk, jumlah, harga_satuan):
        self.produk = produk
        self.jumlah = jumlah
        self.harga_satuan = harga_satuan

    def total(self):
        return self.jumlah * self.harga_satuan

    def info(self):
        return f"{self.produk} x{self.jumlah} = Rp{self.total():,}"

data = [("Kopi", 3, 15000), ("Teh", 2, 8000), ("Kopi", 1, 15000)]

transaksi = [Transaksi(p, j, h) for p, j, h in data]
omzet = sum(t.total() for t in transaksi)

for t in transaksi:
    print(t.info())
print("Total omzet: Rp", f"{omzet:,}")

Perhatikan: logika "total = jumlah x harga" tertulis sekali di method total(), lalu dipakai di mana-mana. Kalau aturan berubah (misal tambah pajak), kamu mengedit satu method saja.

Sekilas inheritance: cetakan turunan

Class bisa mewarisi class lain, lalu menambah atau mengubah perilakunya:

python
class ProdukDiskon(Produk):
    def __init__(self, nama, harga, diskon_persen):
        super().__init__(nama, harga)
        self.diskon_persen = diskon_persen

    def info(self):
        akhir = self.harga * (1 - self.diskon_persen / 100)
        return f"{self.nama}: Rp{akhir:,.0f} (diskon {self.diskon_persen}%)"

promo = ProdukDiskon("Kopi Tubruk", 15000, 20)
print(promo.info())  # Kopi Tubruk: Rp12,000 (diskon 20%)

super().__init__(...) memanggil constructor class induk, lalu class anak menambah diskon_persen dan menimpa info(). Cukup sampai sini untuk kebutuhan analyst: fokusmu tetap memakai objek (pandas), bukan merancang hierarki class.

Kesalahan umum pemula

SALAH: Lupa self di definisi method.

python
class Produk:
    def info():          # TypeError saat dipanggil!
        return "info"

BENAR: Method selalu menerima self sebagai parameter pertama:

python
class Produk:
    def info(self):
        return f"{self.nama}: Rp{self.harga:,}"

SALAH: Mengakses atribut yang tidak pernah di-set di __init__.

python
class Produk:
    def __init__(self, nama):
        self.nama = nama

kopi = Produk("Kopi")
print(kopi.harga)   # AttributeError: 'Produk' object has no attribute 'harga'

BENAR: Set semua atribut yang dibutuhkan di __init__:

python
class Produk:
    def __init__(self, nama, harga):
        self.nama = nama
        self.harga = harga

SALAH: Mengira mengubah satu objek mengubah semua objek (atau sebaliknya).

python
kopi = Produk("Kopi", 15000)
teh = Produk("Teh", 8000)
kopi.harga = 16000   # hanya kopi yang berubah
print(teh.harga)     # 8000, teh tidak ikut berubah

BENAR: Setiap objek punya datanya sendiri (yang disimpan lewat self). Mengubah kopi.harga tidak menyentuh teh.harga. Inilah gunanya cetakan: banyak kue, masing-masing punya isi sendiri.

SALAH: Memanggil method tanpa tanda kurung, lalu heran kenapa tidak jalan.

python
print(kopi.info)    # <bound method ...>, bukan hasilnya!

BENAR: Method dipanggil dengan kurung, seperti fungsi:

python
print(kopi.info())  # Kopi: Rp16,000

Tantangan

Class Transaksi

Buat class Transaksi dengan __init__(produk, jumlah, harga_satuan) dan method total() yang mengembalikan jumlah*harga. Buat 2 objek, print total masing-masing dan total gabungan.