Attribute menyimpan keadaan; instance method adalah perilaku yang membaca dan mengubah keadaan itu. Selama dua chapter terakhir kita sudah berkali-kali memanggil method seperti buku.deskripsi() tanpa membedah apa yang sebenarnya terjadi di balik tanda kurung itu. Chapter ini membongkarnya: bagaimana self dikirim, dua notasi pemanggilan yang setara, method sebagai attribute biasa, dan cara membuat object kita ramah saat dicetak lewat __repr__.

Method Menerima self Secara Otomatis #

Aturan mainnya satu kalimat: object.method(argumen) hanyalah bentuk ringkas dari Class.method(object, argumen). Ketika interpreter menemukan buku.pinjam("Budi"), interpreter mencari fungsi pinjam di class, lalu mengoper buku sebagai argumen pertama secara otomatis. Kedua notasi berikut menghasilkan hal yang persis sama:

python
class Buku:
    def __init__(self, judul, penulis):
        self.judul = judul
        self.penulis = penulis

    def pinjam(self, peminjam):
        return f"{self.judul} dipinjam oleh {peminjam}"

buku = Buku("Laskar Pelangi", "Andrea Hirata")

print(buku.pinjam("Budi"))
print(Buku.pinjam(buku, "Siti"))

Output yang Dihasilkan:

text
Laskar Pelangi dipinjam oleh Budi
Laskar Pelangi dipinjam oleh Siti

Mari kita telaah baris-baris kode di atas:

  1. Baris 6-7 (def pinjam(self, peminjam):): method menerima dua parameter — self yang diisi interpreter, dan peminjam yang diisi pemanggil.
  2. Baris 11 (print(buku.pinjam("Budi"))): notasi sehari-hari. Object buku dioper ke parameter self secara diam-diam.
  3. Baris 12 (print(Buku.pinjam(buku, "Siti"))): notasi penuh melalui class. Object ditulis eksplisit sebagai argumen pertama — hasilnya identik.

Kedua notasi punya kegunaan masing-masing: notasi instance untuk kode aplikasi, notasi class biasa dipakai ketika kita hanya memegang class dan object secara terpisah — misalnya di dalam fungsi yang menerima keduanya sebagai parameter.

Method adalah Attribute Biasa #

Di Python, method menempel pada object seperti attribute lain — ia hanya kebetulan bisa dipanggil (callable). Kita bisa mengambilnya tanpa menjalankannya:

python
class Buku:
    def __init__(self, judul):
        self.judul = judul

    def deskripsi(self):
        return f"Buku berjudul {self.judul}"

buku = Buku("Bumi Manusia")
method_yang_disimpan = buku.deskripsi

print(type(method_yang_disimpan))
print(method_yang_disimpan())

Output yang Dihasilkan:

text
<class 'method'>
Buku berjudul Bumi Manusia

Perhatikan dua hal dari kode di atas. Pertama, buku.deskripsi tanpa tanda kurung tidak menjalankan apa pun — ekspresi itu hanya mengambil method sebagai object, sama seperti mengambil angka dari buku.judul. Kedua, method_yang_disimpan() masih tetap tahu object asalnya: method tersebut terikat (bound) ke buku, sehingga self di dalamnya tetap merujuk buku meskipun dipanggil lewat nama variabel lain. Perilaku ini sejalan dengan materi first-class functions pada Section Fungsi — di Python, fungsi dan method adalah nilai yang bisa disimpan dan dilempar seperti data.

repr untuk Cetak yang Ramah #

Coba print(buku) pada class yang belum mendefinisikan apa pun, dan Python hanya menampilkan <__main__.Buku object at 0x7f58a1c2e4d0> — nama class diikuti alamat memori. Angka heksadesimal itu berbeda di setiap komputer dan setiap eksekusi, sehingga tidak informatif untuk dibagikan. Kita bisa menggantinya dengan mendefinisikan method khusus __repr__:

python
class Buku:
    def __init__(self, judul, penulis):
        self.judul = judul
        self.penulis = penulis

    def __repr__(self):
        return f"Buku({self.judul!r}, {self.penulis!r})"

buku = Buku("Laskar Pelangi", "Andrea Hirata")

print(buku)
print([buku])

Output yang Dihasilkan:

text
Buku('Laskar Pelangi', 'Andrea Hirata')
[Buku('Laskar Pelangi', 'Andrea Hirata')]

Mari kita telaah baris-baris kode di atas:

  1. Baris 6-7 (def __repr__(self):): fungsi print() memanggil __repr__ secara otomatis setiap kali object perlu ditampilkan sebagai teks — mekanisme yang sama dengan __init__ yang dipanggil otomatis saat object dibuat.
  2. Baris 7 ({self.judul!r}): conversion !r memakai bentuk repr string, sehingga hasilnya tetap memakai tanda kutip — memudahkan membedakan string "Laskar Pelangi" dari teks biasa.
  3. Baris 12 (print([buku])): __repr__ juga dipakai saat object berada di dalam container seperti list, jadi struktur data yang dicetak tetap terbaca.

Konvensi umum: __repr__ sebaiknya berisi teks yang bisa menolong debugging — minimal nama class dan data kuncinya. Keluarga besar method khusus berawalan dua underscore (__init__, __repr__, hingga __len__ yang akan kita temui lagi di Chapter Polymorphism) dibahas lengkap pada chapter Special Methods dan Data Model di Section Advanced Data Modeling.