Metode pada kelas Python terbagi atas tiga jenis menurut argumen pertamanya, yaitu metode instans dengan self, metode kelas dengan cls, dan metode statis tanpa keduanya. Ketiganya dideklarasikan di badan kelas yang sama, tetapi jangkauan data yang dapat diaksesnya berbeda. Topik ini membahas karakter setiap jenis, kasus penggunaannya yang khas, serta perbandingan lengkap untuk memilih dengan tepat.
Metode instans: perilaku objek#
Metode instans adalah bentuk metode paling umum dan tidak memerlukan decorator apa pun. Parameter pertamanya, yaitu self, menerima instans pemanggil, sehingga metode ini bebas membaca dan mengubah atribut objek tersebut. Metode jenis inilah tempat menaruh perilaku yang menyentuh data per objek.
class Keranjang:
def __init__(self):
self.item = []
def tambah(self, nama):
self.item.append(nama)
def jumlah(self):
return len(self.item)
k = Keranjang()
k.tambah("buku")
k.tambah("penggaris")
print(k.jumlah())2Metode tambah() dan jumlah() bekerja sepenuhnya pada atribut self.item milik instans k. Setiap keranjang lain yang dibuat dari kelas yang sama membawa list-nya sendiri, sehingga tidak ada data yang tercampur. Metode instans juga satu-satunya jenis yang dapat mengubah atribut objek, karena hanya parameter self yang membawa instansnya ke dalam metode. Apabila metode tidak menyertakan return, pemanggilannya menghasilkan None, dan perubahan yang dilakukan tetap tersimpan pada atribut objek, bukan pada nilai kembali. Apabila sebuah operasi membutuhkan isi objek, metode instans adalah pilihan yang tepat tanpa perlu dipertimbangkan lagi.
Metode kelas: konstruktor alternatif#
Metode kelas dideklarasikan dengan decorator @classmethod, yaitu tanda @ di atas definisi metode yang mengubah perilakunya. Parameter pertama, yaitu cls, menerima kelas, bukan instans, sehingga metode ini tidak dapat membaca atribut objek tertentu. Kegunaannya yang paling khas adalah konstruktor alternatif, yaitu fungsi pabrik yang mengembalikan instans baru dari data berbentuk lain.
class Durasi:
def __init__(self, menit):
self.menit = menit
@classmethod
def dari_teks(cls, teks):
jam, menit = teks.split(":")
return cls(int(jam) * 60 + int(menit))
d = Durasi.dari_teks("1:30")
print(d.menit)
print(type(d).__name__)90
DurasiMetode dari_teks() menerima teks berformat jam dan menit, mengonversinya menjadi total menit, lalu memanggil cls(...) untuk membuat instans baru. Pemanggilan cls alih-alih menuliskan Durasi secara langsung membuat pabrik ini bekerja dengan benar pula pada subclass, karena cls berisi kelas yang benar-benar dipanggil, bukan selalu kelas tempat metode didefinisikan. Satu kelas dapat memiliki beberapa konstruktor alternatif sekaligus, dan penamaannya lazim diawali dari_.
Selain menjadi pabrik, metode kelas juga tempat yang tepat untuk membaca atau mengubah state pada tingkat kelas, misalnya penghitung jumlah instans atau daftar turunan yang terdaftar. Karena cls merujuk kelasnya, atribut semacam itu dijangkau tanpa memerlukan instans apa pun. Apabila logikanya tidak menyentuh kelas maupun instans, metode statislah tempatnya.
Metode statis: utilitas terkait kelas#
Metode statis dideklarasikan dengan decorator @staticmethod dan tidak menerima self maupun cls. Fungsinya seperti fungsi biasa, tetapi ditempatkan di dalam kelas karena maknanya berhubungan dengan tipe tersebut. Metode ini tidak dapat menyentuh atribut instans maupun atribut kelas, sehingga cocok untuk pemeriksaan dan konversi mandiri.
class Durasi:
@staticmethod
def ringkas(total_menit):
return f"{total_menit // 60} jam {total_menit % 60} menit"
print(Durasi.ringkas(90))
print(Durasi.ringkas(45))1 jam 30 menit
0 jam 45 menitMetode ringkas() tidak membutuhkan data objek atau kelas apa pun, sehingga bentuk statisnya tepat. Penempatan di dalam kelas tetap memberi manfaat, yaitu fungsi ini ditemukan bersama tipe yang ia layani dan ruang lingkup modulnya tidak bertambah. Metode statis dapat dipanggil melalui kelas maupun melalui instans, dan keduanya menjalankan fungsi yang sama tanpa argumen tambahan. Apabila kelak metode ini membutuhkan akses ke kelas, decorator @staticmethod diganti dengan @classmethod tanpa mengubah pemanggilnya.
Membandingkan ketiga jenis metode#
Tabel berikut merangkum perbedaan ketiga jenis metode dari sisi parameter dan kegunaannya. Baris parameter pertama adalah pembeda paling mendasar, karena di situlah Python menempelkan instans atau kelas secara otomatis.
| Aspek | Metode instans | Metode kelas | Metode statis |
|---|---|---|---|
| Parameter pertama | self, instans pemanggil | cls, kelas pemanggil | tidak ada |
| Akses atribut instans | tersedia | tidak tersedia | tidak tersedia |
| Akses kelasnya | melalui self.__class__ | langsung melalui cls | tidak ada |
| Kegunaan umum | perilaku objek | konstruktor alternatif, status kelas | utilitas mandiri |
Berkas berikut memadukan ketiga jenis pada satu kelas Suhu, lengkap dengan pemanggilannya.
class Suhu:
def __init__(self, celsius):
self.celsius = celsius
# metode instans: membaca atribut objek
def ke_fahrenheit(self):
return self.celsius * 9 / 5 + 32
# metode kelas: konstruktor alternatif
@classmethod
def dari_fahrenheit(cls, nilai):
return cls((nilai - 32) * 5 / 9)
# metode statis: pemeriksaan mandiri
@staticmethod
def valid(nilai):
return nilai >= -273.15
s = Suhu.dari_fahrenheit(212)
print(s.celsius)
print(s.ke_fahrenheit())
print(Suhu.valid(100.0))
print(Suhu.valid(-300.0))100.0
212.0
True
FalseSimpan berkas di atas di direktori kerja, lalu jalankan dengan perintah berikut.
# menjalankan program kelas Suhu
python3 suhu.py100.0
212.0
True
FalseAlurnya menunjukkan pembagian peran yang rapi. Konstruktor alternatif dari_fahrenheit() menghasilkan instans dengan nilai 100.0, metode instans ke_fahrenheit() membaca atribut objek tersebut dan mengembalikan 212.0, sedangkan metode statis valid() memeriksa nilai tanpa menyentuh objek. Keluaran False untuk -300.0 menegaskan batas nol absolut yang diperiksa metode statisnya.
Satu kelas menyimpan ketiga jenis metode tanpa konflik apa pun, karena pembedanya terletak pada decorator dan parameter pertama masing-masing metode. Pembaca kode dapat mengenali perannya dengan cepat dari bentuk tersebut, dan alat bantu seperti editor menampilkan tanda tangannya dengan benar.
Kesalahan umum#
Kesalahan pertama adalah lupa menuliskan decorator @classmethod pada metode pabrik, sehingga parameter pertama tidak lagi menerima kelasnya.
class Durasi:
def dari_teks(cls, teks):
jam, menit = teks.split(":")
return cls(int(jam) * 60 + int(menit))
try:
d = Durasi.dari_teks("1:30")
except TypeError as e:
print(type(e).__name__, str(e))TypeError Durasi.dari_teks() missing 1 required positional argument: 'teks'Tanpa decorator, dari_teks dianggap metode instans biasa, sehingga Python memperlakukan "1:30" sebagai cls dan menganggap teks tidak terisi. Pesan errornya menyebut argumen teks yang hilang, padahal akar masalahnya adalah parameter pertama. Menambahkan @classmethod di atas definisi metode menyelesaikannya.
Kesalahan kedua adalah memakai metode statis untuk pekerjaan yang ternyata membutuhkan data kelas atau objek. Metode semacam itu akhirnya menerima nilai melalui parameter yang seharusnya dibaca dari cls atau self, sehingga pemanggilnya terbebani. Apabila kebutuhan tersebut muncul, pindahkan logikanya ke metode kelas atau metode instans. Sebaliknya, menaruh fungsi utilitas yang benar-benar mandiri ke luar kelas juga sah, apabila fungsinya tidak berhubungan dengan tipe mana pun.
Ringkasan#
- Metode instans menerima
selfdan menjadi tempat perilaku yang menyentuh atribut objek. - Metode kelas menerima
clsdan lazim dipakai sebagai konstruktor alternatif yang tetap benar pada subclass. - Metode statis tidak menerima
selfmaupunclsdan berperan sebagai utilitas yang berhubungan dengan tipe tersebut. - Parameter pertamanya adalah pembeda utama ketiganya, sehingga kebutuhan akses data menentukan pilihan jenis metode.
Referensi#
- classmethod — Python Software Foundation
— Dokumentasi bawaan
classmethodbeserta contoh konstruktor alternatifnya. - staticmethod — Python Software Foundation
— Dokumentasi bawaan
staticmethoddan karakternya pada subclass. - Descriptor HowTo Guide — Python Software Foundation — Penjelasan mekanisme yang mendasari classmethod dan staticmethod.