Apa itu Magic Method?
Magic method dalam python adalah method-method spesial yang namanya diawali dan diakhiri dengan dobel underscore. Magic method sendiri tidak dirancang untuk kita panggil secara langsung, akan tetapi ia akan dipanggil oleh sistem secara internal pada saat-saat tertentu seperti misalnya saat membuat sebuah objek atau melakukan operator +
, -
, dan lain sebagainya [1].
Di dalam python, magic method juga dinamakan dengan dunder method. Dimanakan “dunder” karena ia merupakan singkatan dari “double underscore” [2].
Kita sebenarnya telah menggunakan beberapa magic method pada pembahasan konstruktor kelas dan juga pembahasan operator overloading. Di antara contoh magic method yang telah kita pelajari adalah:
- Method
__init__()
- Method
__add__()
- Method
__sub__()
- Method
__mul__()
- Method
__truediv__()
- dan lain sebagainya
Method-method tersebut tidak kita panggil secara eksplisit, karena ia dipanggil otomatis oleh sistem ketika sebuah aksi tertentu dilakukan.
Bedanya Magic Method dan Operator Overloading
Pada pertemuan sebelumnya kita telah membahas panjang lebar tentang teknik operator overloading, ia adalah teknik di mana kita bisa mengatur behaviour suatu kelas atau objek ketika dikenakan sebuah operator.
Apa bedanya dengan magic method?
Magic method adalah method khusus yang memiliki nama diawali serta diakhiri dengan dobel underscore (__
). Method-method tersebut ada banyak sekali dengan berbagai tugas yang beragam.
Nah, di antara magic method tersebut, ada method-method yang kita gunakan untuk melakukan teknik operator overloading seperti method __add__()
, __sub__()
, dan lain-lain.
Contoh:
class Angka:
def __init__(self, angka):
self.angka = angka
def __add__(self, objek):
return self.angka + objek.angka
Ketika kita panggil:
x1 = Angka(10)
x2 = Angka(20)
print(x1 + x2)
Konstruktor Juga Termasuk Magic Method
Sadar atau tidak sadar, ketika kita membuat sebuah konstruktor dalam suatu kelas, maka sejatinya kita telah menggunakan salah satu di antara magic method yang terdapat pada python.
Perhatikan contoh berikut:
class HaloDunia:
def __init__(self):
print('Halo dunia')
# buat instan
a = HaloDunia()
b = HaloDunia()
Output:
Halo dunia
Halo dunia
Kita bisa perhatikan pada contoh di atas, bahwa kita tidak pernah memanggil fungsi __init__()
sama sekali. Akan tetapi sistem tetap memanggilnya secara otomatis ketika ada pembuatan instan dari kelas HaloDunia
.
Method __str__()
Di antara magic method yang sangat banyak digunakan adalah method: __str__()
.
Method __str__()
akan dipanggil ketika sebuah instan dari kelas yang bersangkutan dikonversi menjadi string atau ketika dijadikan parameter untuk fungsi print()
.
Perhatikan contoh berikut:
class Segitiga:
def __init__(self, a, t):
self.alas = a
self.tinggi = t
# buat instan
a = Segitiga(10, 10)
b = Segitiga(20, 10)
print(a)
print(b)
Apa outputnya?
Outputnya adalah kode yang tidak manusiawi alias tidak jelas seperti berikut:
<__main__.Segitiga object at 0x7f80d82dabe0>
<__main__.Segitiga object at 0x7f80d82dac10>
Lalu bagaimana misalkan instan dari kelas yang kita buat (dalam hal ini adalah kelas Segitiga
) bisa menampilkan string tertentu ketika di-print()
?
Jawabannya adalah: gunakan magic method __str__()
.
Perhatikan contoh berikut:
class Segitiga:
def __init__(self, a, t):
self.alas = a
self.tinggi = t
def __str__(self):
luas = 0.5 * self.alas * self.tinggi
return f'segitiga (alas={self.alas} tinggi={self.tinggi} luas={luas})'
# buat instan
a = Segitiga(10, 10)
b = Segitiga(20, 10)
print(a)
print(b)
Output:
segitiga (alas=10 tinggi=10 luas=50.0)
segitiga (alas=20 tinggi=10 luas=100.0)
Method __repr__()
Hampir sama dengan method __str__()
, method __repr__()
juga akan mengembalikan sebuah string. Bedanya, method __repr__()
hanya akan dipanggil ketika kita memanggil default function repr()
pada python.
Perhatikan contoh berikut:
class Contoh:
def __str__(self):
return 'bentuk informal'
def __repr__(self):
return 'bentuk formal'
x = Contoh()
print(x)
print(str(x))
print(repr(x)) # kalau tidak diprint tidak ada output
Output:
bentuk informal
bentuk informal
bentuk formal
Method __len__()
Di antara magic method yang cukup umum digunakan adalah: method __len__()
.
Ia adalah sebuah method yang akan dipanggil ketika sebuah objek atau instan dijadikan parameter untuk fungsi bawaan python len()
.
Perhatikan contoh berikut:
class Siswa:
def __init__(self):
self.__list_siswa = []
def tambah_siswa(self, siswa):
self.__list_siswa.append(siswa)
grup1 = Siswa()
grup1.tambah_siswa('Huda')
print(len(grup1))
Jika kita jalankan, kita justru akan mendapatkan error:
TypeError: object of type 'Siswa' has no len()
Itu kenapa? Karena objek dari tipe Siswa
tidak memiliki fungsi len()
alias ia tidak mengimplementasikan magic method yang bernama __len__()
.
Beda ceritanya jika kita ubah kodenya menjadi berikut:
class Siswa:
def __init__(self):
self.__list_siswa = []
def tambah_siswa(self, siswa):
self.__list_siswa.append(siswa)
def __len__(self):
return len(self.__list_siswa)
grup1 = Siswa()
grup1.tambah_siswa('Huda')
grup1.tambah_siswa('Wahid')
print(len(grup1))
Output:
2
Method __getitem__()
Masih satu paket dengan fungsi __len__()
. Fungsi __getitem__()
adalah sebuah magic method yang akan dipanggil ketika sebuah instan dari kelas yang kita buat dipanggil menggunakan indeks yang diapit dengan kurung siku []
.
Mari kita lanjutkan kode program sebelumnya untuk kelas Siswa
, kemudian kita akses instan dari kelas tersebut dengan kurung siku seperti berikut:
grup1 = Siswa()
grup1.tambah_siswa('Huda')
grup1.tambah_siswa('Wahid')
print(grup1[0])
Kita akan mendapatkan error:
TypeError: 'Siswa' object is not subscriptable
Nah, agar tidak error, kita bisa mengimplementasikan fungsi __getitem__()
:
class Siswa:
def __init__(self):
self.__list_siswa = []
def tambah_siswa(self, siswa):
self.__list_siswa.append(siswa)
def __len__(self):
return len(self.__list_siswa)
def __getitem__(self, position):
return self.__list_siswa[position]
grup1 = Siswa()
grup1.tambah_siswa('Huda')
grup1.tambah_siswa('Wahid')
print(grup1[0])
Jika kita jalankan, kita akan mendapatkan output:
Huda
Bahkan, kita juga bisa memasukkan variabel grup1
ke dalam perulangan for:
# bisa juga pakai for
for siswa in grup1:
print(siswa)
Output:
Huda
Wahid
Method-Method Yang Lain
Selain method-method yang sudah kita coba di atas, masih ada banyak sekali magic method lain yang terdapat pada python.
Untuk mengetahui apa saja magic method yang diimplementasikan pada suatu kelas (atau tipe data), kita bisa memanggil fungsi dir()
.
Perhatikan contoh berikut:
>>> dir(int)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__',
'__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__',
'__float__', '__floor__', '__floordiv__', '__format__', '__ge__',
'__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__',
'__init__', '__init_subclass__', '__int__', '__invert__', '__le__',
'__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__',
'__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__',
'__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__',
'__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__',
'__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
'__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',
'__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',
'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag',
'numerator', 'real', 'to_bytes']
Pada contoh di atas kita telah menampilkan fungsi magic apa saja yang telah diimplementasikan dalam tipe data int
.
Agar lebih terlihat bedanya, mari kita lihat output dari tipe data str
:
>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__len__', '__lt__',
'__mod__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold',
'center', 'count', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii',
'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric',
'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust',
'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix',
'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',
'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip',
'swapcase', 'title', 'translate', 'upper', 'zfill']
Berbeda bukan?
Kesimpulan
Dari pertemuan kali ini, kita bisa simpulkan bahwa:
- Magic method adalah method khusus pada python, namanya sudah ditentukan oleh sistem, dan pasti diawali serta diakhiri dengan tanda double underscores (
__
). - Magic method tidak kita panggil secara eksplisit, melainkan akan dipanggil secara otomatis oleh sistem ketika terjadi suatu keadaan tertentu.
- Kita bisa memeriksa magic method apa saja yang diimplementasikan pada suatu kelas dengan memanggil fungsi
dir(tipe)
Kode Program Lengkap
Untuk kode program lengkap pada pertemuan kali ini, kalian bisa mendapatkannya di sini.
Pertemuan Selanjutnya
Pada pertemuan selanjutnya insyaallah kita akan membahas tentang destruktor pada python.
Ia merupakan aksi yang dilakukan tepat ketika sebuah data akan dihapus dari dalam memori.
Bagaimana caranya?
Simak terus tutorial ini, ya! Terima kasih banyak.
Referensi
[1] https://www.tutorialsteacher.com/python/magic-methods-in-python – diakses tanggal 28 Mei 2021
[2] https://www.geeksforgeeks.org/dunder-magic-methods-python/ – diakses tanggal 28 Mei 2021